CF 1867 E1. Salyg1n and Array (simple version)

发布时间 2023-09-18 19:57:06作者: Simex

Link

简单版本的结论还是很容易猜到的。

首先很容易想到的第一步就是尽可能地不覆盖地取尽可能多地区间,最后剩下了一小块。

然后在接着原来的指针一个一个地往右问,直到不能问了为止。

为什么这样是正确的呢?首先,在这样一步一步地往右查询的过程中,我们会发现总是前$k-1个数加上后面的一个数。

然后题面中把EVEN加粗了,因为你会发现,如果这样操作,前 \(k-1\)个数在实际上只会出现奇数次

这样把问到的一堆东西异或起来就是答案了。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<ctime>
#include<bitset>
using namespace std;
int t;
int n,k;
long long ans;
int ask(int f){
	cout<<"? "<<f<<endl;
	int x;
	cin>>x;
	return x;
	
}
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&k);
		int f;
		ans=0;
		for(f=1;f+2*k-1<=n;f+=k){
			ans^=ask(f);
		}
		for(;f+k-1<=n;++f){
			ans^=ask(f);
		}
		cout<<"! "<<ans<<endl;
	}
	return 0;
}