1. 程式人生 > 其它 >【做題記錄】CF1451E2 Bitwise Queries (Hard Version)

【做題記錄】CF1451E2 Bitwise Queries (Hard Version)

CF1451E2 Bitwise Queries (Hard Version)

題意:

\(n\) 個數( \(n\le 2^{16}\) ,且為 \(2\) 的整數次冪,且每一個數都屬於區間 \([0,n-1]\) ) 可以通過詢問互動庫不超過 \(n+1\) 次詢問,每次詢問編號為 \(i,j\)\(1\le i,j \le n\)\(i\ne j\) ) 的 XORORAND ,求出這 \(n\) 個數 。

題解:

分類討論,先對 \(2-n\)\(n-1\) 個數每個數都與 \(1\) 詢問一次 XOR ,之後考慮 \(2\) 次求出 \(a_1\)

  • 所有數都互不相同

    此時所有 \(xor\) 值都不相同且都不等於 \(0\) ,可以分別找出 \(xor_i=1\)\(xor_j=n-2\) 的數,用 \(1\) 一次 \(and\) 詢問求出 \(a_1\) 的前 \(m\) 位與最後一位 。

  • 有些數相同

    那些數的 \(xor\) 值相同 。

    • 有些數與 \(a_1\) 相同

      找出 \(xor_i=0\) 的數,與 \(1\) 詢問 AND ,直接求出 \(a_1\)

    • 有些數相同,但不等於 \(a_1\)

      找出兩個 \(xor\) 相同的數,用 \(1\) 次詢問求出 \(a_i\) ,進而用之前詢問求得的 \(xor_i\) 求出 \(a_1\)

程式碼:

#include<bits/stdc++.h>
using namespace std;
#define Maxn 65540
inline int rd()
{
	 int x=0;
     char ch,t=0;
     while(!isdigit(ch = getchar())) t|=ch=='-';
     while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
     return x=t?-x:x;
}
int n,Xor[Maxn],ans[Maxn],vis[Maxn];
bool All=true;
inline int XOR(int x,int y)
{
	 printf("XOR %d %d\n",x,y),fflush(stdout);
	 return rd();
}
inline int AND(int x,int y)
{
	 printf("AND %d %d\n",x,y),fflush(stdout);
	 return rd();
}
int main()
{
     //freopen(".in","r",stdin);
     //freopen(".out","w",stdout);
	 n=rd();
	 for(int i=2;i<=n;i++)
	 {
	 	 Xor[i]=XOR(1,i);
	 	 if(vis[Xor[i]] || Xor[i]==0) All=0;
	 	 vis[Xor[i]]=1;
	 }
	 if(All)
	 {
	 	 for(int i=2;i<=n;i++)
	 	 {
	 	 	 if(Xor[i]==1) ans[1]|=AND(1,i);
	 	 	 if(Xor[i]==n-2) ans[1]|=AND(1,i);
		 }
	 }
	 else
	 {
	 	 if(vis[0])
	 	 {
	 	 	 for(int i=2;i<=n;i++) if(!Xor[i]) { ans[1]=AND(1,i); break; }
		 }
		 else
		 {
		 	 for(int i=0;i<=n-1;i++) vis[i]=0;
		 	 for(int i=2;i<=n;i++)
		 	 {
		 	 	 if(vis[Xor[i]]) { ans[1]=Xor[i]^AND(vis[Xor[i]],i); break; }
				 vis[Xor[i]]=i;
			 }
		 }
	 }
	 for(int i=2;i<=n;i++) ans[i]=ans[1]^Xor[i];
	 printf("! ");
	 for(int i=1;i<=n;i++) printf("%d%c",ans[i],(i==n)?'\n':' ');
	 fflush(stdout);
     //fclose(stdin);
     //fclose(stdout);
     return 0;
}