Codeforces Round 900 Div3

A.
只要k在a中出现过,就是YES,可以使用一个变量来标记,或者使用哈希。

void solve(){
	
	int n,k;
	cin >> n >> k;
	vector<int>a(n);
	int h[200] = {0};
	for(int i = 0;i<n;i++){
		cin >> a[i];
		h[a[i]]++;
	}
	int id = 0,ma = 0;

	if(h[k]>0){
		cout<<"YES\n";
	}else{
		cout<<"NO\n";
	}
	
}


B.
可以发现,可以构造出连续的较大的数,或者构造出奇数序列

void solve(){
	int n;
	cin >> n;
	if(n==4){
		cout<<"3 4 5 7\n";
		return ;
	}
	if(n==3){
		cout<<"3 4 5\n";
		return;
	}
	for(ll i = 7;i<=n+6;i++){

		cout << i << " \n"[i==n+6];
	}

}


C.
等差数列,求出 前K个数之和(最小),后K个数之和(最大)只需要看x是否在此区间之中。

void solve(){
	ll n,k,x;
	cin >> n >> k >> x;
	ll d = x/k;
	ll yu = x%k;
	if((__int128)k*(k+1)/2>x){
		cout<<"NO\n";
		return;
	}
	if((__int128)k*(n-k)+(__int128)(k)*(k+1)/2<x){
		cout<<"NO\n";
		return;
	}
	// if(yu<=d){
	// 	k++;
	// 	if(yu==d/2&&d&1) k--;
	// }
	int f = 0;
	cout<<"YES\n";



}


D.
首先,对于某一部分,若次数是偶数则无需操作,否则,对其进行反转

 int main(){
    	int t; //number of test cases
    	cin >> t;
    	while(t--){
    		int n, k; //read the input
    		cin >> n >> k;
    		string s;
    		cin >> s;
    		int a[k]; int b[k];
    		for(int i=0; i< k; i++){cin >> a[i]; a[i]--;}
    		for(int i=0; i< k; i++){cin >> b[i]; b[i]--;}
    		int q;
    		cin >> q;
    		int cnt[n+1]={0}; //read and preprocess queries
    		for(int i=0; i< q; i++){
    			int x; cin >> x; cnt[x-1]++;
    		}
    		string ans="";
    		for(int i=0; i<k; i++){ //treat each interval as a seperate test case
    			string s1=s.substr(a[i], b[i]-a[i]+1);
    			int sum=0;
    			int l=a[i];
    			int r=b[i];
    			for(int j=l; j<=(l+r)/2; j++){
    				sum+=cnt[j]+cnt[r-j+l];
    				if(sum&1)swap(s1[j-l], s1[r-j]);
    			}
    			ans+=s1;
    		}
    		cout << ans << '\n';
    	}
    }


E.
我的做法是预处理数组,求出每一位的前缀和,这样只需要二分答案,利用前缀和,判断出这一位是否存在然后累加即可。此外还可以使用线段树或者st表倍增出预处理。

int pre[200002][30];
void solve(){
	int n;
	cin >> n;
	vector<int>a(n);
	for(int i = 0;i<n;i++){
		cin >> a[i];
	}
	// cout<<1;
	for(int i = 0;i<n;i++){
		for(int j = 0;j<30;j++){
			pre[i+1][j] = pre[i][j];
			if(a[i]&(1<<j)){
				pre[i+1][j]++;
			}
		}
	}

	int q;
	cin >> q;
	while(q--){
		int l,k;
		cin >> l >> k;
		if(a[l-1]<k){
			cout<<-1<<' ';
			continue;
		}
		int sl = l,sr = n;
		while(sl<=sr){
			int mid = (sl+sr)>>1;
			int num = 0;
			for(int i = 0;i<30;i++){
				if(pre[mid][i] - pre[l-1][i] == mid - l + 1){
					num += (1<<i);
				}
			}
			if(num>=k){
				  sl = mid + 1;
			}else sr = mid - 1;
		}
		cout<<sl-1<<' ';
	}
	cout<<'\n';

}


 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值