A .因为只能跳一次 如果没有0 就输出0 否则就输出第一个0到最后一个0 的l-r+2
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
const int INF=0x3f3f3f3f;
const int N=2e5+10,M=1e6+10;
int a[N],mp[M]={0};
void solve(){int n;cin>>n;int l=0,r=0;for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++){if(a[i]==0){l=i;break;}}for(int i=n;i>=1;i--){if(a[i]==0){r=i;break;}}if(l==0&&r==0)cout<<0<<'\n';else cout<<r-l+2<<'\n';
}
signed main(){ios::sync_with_stdio(false);cin.tie(0);int t;cin>>t;//int t=1;while(t--){solve();}
}
B. 如果某一位选手的传球次数大于总次数sum/2 那么其他选手的传球次数总和就是 sum-x;那么需要这个选手的单独传球次数就是 x-(sum-x)-1 所需球的数量就是 x-(sum-x)-1+1; 否则的话就是 1
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
const int INF=0x3f3f3f3f;
const int N=2e5+10,M=1e6+10;
int a[N],mp[M]={0};
void solve(){int n;cin>>n;int maxx=0,sum=0;for(int i=1;i<=n;i++){int x;cin>>x;maxx=max(maxx,x);sum+=x;}if(maxx==0)cout<<0<<'\n';else if(sum<2*maxx)cout<<maxx-(sum-maxx)<<'\n';else cout<<1<<'\n';
}
signed main(){ios::sync_with_stdio(false);cin.tie(0);int t;cin>>t;//int t=1;while(t--){solve();}
}
C. 因为是哈夫曼距离 肯定是可以分开求 我们先考虑x 那么答案就是 x1 x2 x3 ..xn 的两两距离求和首先 如果x均不重复 那么我们可以前缀和 将他们的差值进行前缀和 eg: 1 2 3 =4 差值就是1 1 前缀和就是 1 2 可以 维护一个单点前缀和遍历 如果是 1 1 2 2 3 4 4 我们维护单点前缀和的话就可以 eg3: 3-1+3-1+3-2+3-2=6 == 3*4-1-1-2-2 所以单点前缀和的通项公式xi*(i+1)-sum;
或者推公式
我们也是分开求 那么第一个就是 i j 的|ri-rj| 变成 i j 的 si -sj 再化简 最后 就是 j次的 sj 和 (k-i+1)次的si
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
const int INF=0x3f3f3f3f;
const int N=2e5+10,M=1e6+10;
int a[N],mp[M]={0};
map<int,vector<int>> mp1,mp2;int go(map<int,vector<int>> &v){int ans=0;for(auto k: v){auto s=k.second;sort(s.begin(),s.end());int sum=0;int cnt=0;for(auto j: s){ans+=j*cnt-sum;cnt++;sum+=j; }}return ans;
}
void solve(){int n,m;cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){int x;cin>>x;mp1[x].pb(i);mp2[x].pb(j);}}cout<<go(mp1)+go(mp2)<<'\n';
}
signed main(){ios::sync_with_stdio(false);cin.tie(0);//int t;cin>>t;int t=1;while(t--){solve();}
}
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1000, M =100005;
int g[N][N];
vector<int> vx[M], vy[M];
int main() {int n, m;cin >> n >> m;for(int i = 1; i <= n; i++) {for(int j = 1; j <= m; j ++) {cin >> g[i][j];vx[g[i][j]].push_back(i);vy[g[i][j]].push_back(j);}}for(int i = 1; i <= M; i++) {sort(vx[i].begin(), vx[i].end());sort(vy[i].begin(), vy[i].end());}long long ans;for(int i = 1; i <= M; i ++) {for(int j = 0; j < vx[i].size(); j ++) {ans += vx[i][j] * (2j + 1 - vx[i].size());ans += vy[i][j] * (2j + 1 - vy[i].size());}}cout << ans << endl;
}
D. 我们直接暴力枚举每个数的倍数区间 如果这个数的倍数区间里有数就可 前缀和实现区间的数的个数 a/b==k 我们就只需枚举[ b*k,b*(k+1)-1]这个倍数区间里面有没有数即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
const int INF=0x3f3f3f3f;
const int N=1e6+10,M=1e6+10;
int a[N],mp[M]={0};
int s[N];
void solve(){int n,c;cin>>n>>c;for(int i=1;i<=c;i++)mp[i]=s[i]=0;for(int i=1;i<=n;i++){int x;cin>>x;mp[x]=1;}if(!mp[1]){cout<<"No"<<'\n';return ;}for(int i=1;i<=c;i++)s[i]=s[i-1]+mp[i];for(int i=2;i<=c;i++){if(!mp[i])continue;for(int j=i;j<=c;j+=i){if(s[min(c,i+j-1)]-s[j-1]){if(!mp[j/i]){cout<<"No"<<'\n';return ;}}}}cout<<"Yes"<<'\n';
}
signed main(){ios::sync_with_stdio(false);cin.tie(0);int t;cin>>t;//int t=1;while(t--){solve();}
}
或者暴力枚举i j 如果j 不存在 但是 区间有 就是NO