D.Powerful Ksenia(思維+三元組異或構造)
阿新 • • 發佈:2021-01-23
https://codeforces.com/contest/1438/problem/D
題意:給你一個數組a,大小n,每一次可以選擇一個三元組( i , j , k ) ( i ≠ j ≠ k ) ,然後將ai,aj,ak賦值為aixorajxorak
- 求一個方案使得在n步之內將使得ai全部相同,不行輸出NO。
- n≤1e5
思路:先從特殊的構造入手,再來考慮拓展到其他。
比較特殊的是異或的一個性質。x xor x xor y=y;即通過一次操作可以把兩個相同的數變為第三個數。
於是我們可以考慮到用一定的運算元把序列中若干個數變得相同.
這裡有一個奇偶構造。若奇數一定滿足。
說明如下:
參考:https://zhuanlan.zhihu.com/p/293954703
偶數長度的話拿其n-1,為奇數部分進行構造,將會有n-3次操作變成一個n-1個數相同的序列。如果最後一個數不相同,沒法在3次以內變回來。
#include<iostream> #include<vector> #include<queue> #include<cstring> #include<cmath> #include<map> #include<set> #include<cstdio> #include<algorithm> #define debug(a) cout<<#a<<"="<<a<<endl; using namespace std; const int maxn=1e5+1000; typedef long long LL; LL a[maxn]; void work(LL i,LL j,LL k){ LL t=a[i]^a[j]^a[k]; a[i]=a[j]=a[k]=t; } int main(void) { cin.tie(0);std::ios::sync_with_stdio(false); LL n;cin>>n; for(LL i=1;i<=n;i++){ cin>>a[i]; } if(n&1){ cout<<"YES"<<endl; cout<<n-2<<endl; for(LL i=2;i<=n-3;i+=2){ cout<<i<<" "<<i+1<<" "<<i+2<<endl; } cout<<n-1<<" "<<n<<" "<<1<<endl; for(LL i=2;i<=n-3;i+=2){ cout<<1<<" "<<i<<" "<<i+1<<endl; } } else{ for(LL i=2;i<=n-3-1;i+=2){ work(i,i+1,i+2); } work(n-1-1,n-1,1); if(a[n]!=a[1]){ cout<<"NO"<<endl; } else{ cout<<"YES"<<endl; cout<<n-2-1<<endl; for(LL i=2;i<=n-3-1;i+=2){ cout<<i<<" "<<i+1<<" "<<i+2<<endl; } cout<<n-1-1<<" "<<n-1<<" "<<1<<endl; for(LL i=2;i<=n-3-1;i+=2){ cout<<1<<" "<<i<<" "<<i+1<<endl; } } } return 0; }