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