CodeForces - 1534E Lost Array(bfs+交互)
生活随笔
收集整理的這篇文章主要介紹了
CodeForces - 1534E Lost Array(bfs+交互)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:初始時給出一個長度為 nnn 的序列,每次可以詢問 kkk 個位置的異或和,現在需要以最少的詢問獲得整個序列的異或和
題目分析:因為是異或,我們只關心每個位置被詢問的次數是奇數還是偶數,不妨設置一個集合,將詢問次數為奇數次數的位置都放進來
那么我們初始時的狀態是“集合大小為 000”,目標狀態是“集合大小為 nnn”,可以通過 bfsbfsbfs 去擴展,對于某個狀態 xxx 來說,假設我們需要選擇 jjj 個集合內的數,那么自然需要選擇 k?jk-jk?j 個集合外的數,集合的最終大小會變成 x?j+(k?j)=x+k?2?jx-j+(k-j)=x+k-2*jx?j+(k?j)=x+k?2?j,因為 nnn 比較小,所以可以用 bfsbfsbfs 在 O(nk)O(nk)O(nk) 的時間復雜度內處理出來
然后就是還原路徑的過程了,在 bfsbfsbfs 的過程中記錄一下轉移的路徑,然后正向去模擬即可。雖然話是這么說,但是寫起來確實有些難度,在代碼中加入了不少注釋,可以直接參考代碼
代碼:
// Problem: E. Lost Array // Contest: Codeforces - Codeforces LATOKEN Round 1 (Div. 1 + Div. 2) // URL: https://codeforces.com/contest/1534/problem/E // Memory Limit: 256 MB // Time Limit: 1500 ms // // Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2) // #pragma GCC optimize("Ofast","inline","-ffast-math") // #pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<list> #include<unordered_map> #define lowbit(x) x&-x using namespace std; typedef long long LL; typedef unsigned long long ull; template<typename T> inline void read(T &x) {T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f; } template<typename T> inline void write(T x) {if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0'); } const int inf=0x3f3f3f3f; const int N=1e6+100; int n,k,d[N],pre[N]; bool vis[N]; int query(vector<int>node) {printf("?");for(auto it:node) {printf(" %d",it);}puts("");fflush(stdout);int ans;scanf("%d",&ans);return ans; } void bfs() {memset(d,-1,sizeof(d));queue<int>q;d[0]=0;pre[0]=-1;q.push(0);while(q.size()) {int u=q.front();q.pop();for(int i=0;i<=k;i++) {//選擇i個集合內的數字和(k-i)個集合外的數字if(i>u||k-i>n-u) {continue;}int v=u-i+(k-i);if(d[v]!=-1) {continue;}d[v]=d[u]+1;pre[v]=u;q.push(v);}} } int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);scanf("%d%d",&n,&k);bfs();if(d[n]==-1) {return 0*puts("-1");}vector<int>node;int pos=n;while(pos!=-1) {node.push_back(pos);pos=pre[pos];}reverse(node.begin(),node.end());int ans=0;for(int i=1;i<(int)node.size();i++) {//每次集合的大小需要從node[i-1]變成node[i]//有y=x-delta+(k-delta)=x+k-2*delta,可以計算出delta=(x+k-y)/2int delta=(node[i-1]+k-node[i])/2;vector<int>num;int c0=delta,c1=k-delta;//需要選c0個集合內的數,選c1個集合外的數for(int i=1;i<=n;i++) {if(vis[i]) {//在集合內if(c0>0) {c0--;num.push_back(i);}} else {//不在集合內if(c1>0) {c1--;num.push_back(i);}}}for(auto it:num) {//更新一下每個數是否屬于集合的狀態vis[it]^=1;}ans^=query(num);}printf("! %d\n",ans);return 0; }總結
以上是生活随笔為你收集整理的CodeForces - 1534E Lost Array(bfs+交互)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 上海理工大学第二届“联想杯”全国程序设计
- 下一篇: CodeForces - 1537E2