Codeforces Round #775 (Div. 2, based on Moscow Open Olympiad in Informatics(补)

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值