CF2175B XOR Array
思路
设前缀异或数组为 $pre$,其中 $pre_0=0$,$pre_i= a_1\oplus a_2\oplus\dots\oplus a_i$($\oplus$ 表示异或)。
根据异或的性质,子数组 $a_x\dots a_y$ 的异或和可以表示为:$f(x,y)=pre_y\oplus pre_{x-1}$。
要求 $f(l,r)=0$,等价于 $pre_r=pre_{l-1}$。
要求其余子数组异或和非 $0$,等价于除 $(x,y)=(l,r)$ 外,任意 $i\neq j$ 都有 $pre_i\neq pre_j$。
初始化 $pre_0=0$,$pre_i=i$($1\le i\le n$)。此时 $pre$ 数组元素互不相同,保证所有子数组异或和非 $0$。
调整 $pre_r=pre_{l-1}$,满足 $f(l,r)=0$。由于 $l \le r$,$pre_{l-1}$ 的值不会与 $pre_{1}\dots pre_{r-1}$ 重复,因此调整后仅存在一对相等的前缀值 $pre_{r}$ 和 $pre_{l-1}$。
根据前缀异或的定义,原数组元素 $a_{i}=pre_{i} \oplus pre_{i-1}$,直接计算即可得到答案。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #include<bits/stdc++.h> #define fir first #define sec second #define int long long #define pii pair<int,int> #define fep(i,s,e) for(int i=s;i<e;i++) #define pef(i,s,e) for(int i=s;i>e;i--) #define rep(i,s,e) for(int i=s;i<=e;i++) #define per(i,s,e) for(int i=s;i>=e;i--) namespace FastIO{ template<typename T>inline void read(T &x){ x=0;int f=1;char c=getchar(); for(;!isdigit(c);c=getchar())if(c=='-')f=-1; for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);x*=f; } template<typename T,typename...Args> inline void read(T &x,Args&...args){ read(x);read(args...); } template<typename T>void print(T x){ if(x<0)x=-x,putchar('-'); if(x>9)print(x/10); putchar((x%10)^48); } } using namespace std; using namespace FastIO; const int N=4e5+7; int T,n,l,r; int pre[N]; signed main(){ read(T); while(T--){ read(n,l,r); pre[0]=0; rep(i,1,n)pre[i]=i; pre[r]=pre[l-1]; rep(i,1,n){ int val=pre[i]^pre[i-1]; print(val); if(i<n)putchar(' '); } puts(""); } return 0; }
|