作为一道签到题,自然只能包含最基本的算法。本题的任务很简单,给定一个长度为n的序列a,你要将其排序。
由于出题人很菜,不会排序算法,他决定自己编一个。他想找到一个数x,使得序列中的所有数字都异或上x后序列恰好按从小到大排列。
顺带,这个序列会被进行若干次修改,每次修改后你需要回答当前是否存在一个x满足序列中数字异或上x后按从小到大排列,如果有,请你给出最小的x。
标签:copy using none 接下来 target one splay src 签到
3
0 1 4
3
2 7
3 3
1 4
0
2
-1
4
对于100%的数据,n,m≤106,所有数字不超过230。
请注意输入输出效率对程序运行时间的影响。
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,a[1000005]; int cnt[35][5]; void solve(){ int ret=0; for(int i=30;i>=0;--i){ if(cnt[i][1]&&cnt[i][0]){ printf("-1\n"); return; } if(cnt[i][1]){ ret|=(1<<i); } } printf("%d\n",ret); return; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=2;i<=n;++i){ for(int j=30;j>=0;--j){ if((a[i]^a[i-1])&(1<<j)){ cnt[j][a[i-1]>a[i]]++; break; } } } solve(); int q;scanf("%d",&q); int x,y; while(q--){ scanf("%d%d",&x,&y); if(x>1){ for(int i=30;i>=0;--i){ if((a[x]^a[x-1])&(1<<i)){ cnt[i][a[x-1]>a[x]]--; break; } } for(int i=30;i>=0;--i){ if((y^a[x-1])&(1<<i)){ cnt[i][a[x-1]>y]++; break; } } } if(x<n){ for(int i=30;i>=0;--i){ if((a[x]^a[x+1])&(1<<i)){ cnt[i][a[x]>a[x+1]]--; break; } } for(int i=30;i>=0;--i){ if((y^a[x+1])&(1<<i)){ cnt[i][y>a[x+1]]++; break; } } } a[x]=y; solve(); } return 0; }
标签:copy using none 接下来 target one splay src 签到
原文地址:https://www.cnblogs.com/lllxq/p/10509774.html