P12572 [UOI 2023] An Array and Addition Again 只有数组末尾有一个 1 局限性太大了,考虑先花 99 次操作把整个数组填满 1。 之后直接往后面 DFS 即可,即减去当前位置的 1,除以 2,就是下一个位置需要达到的数,复杂度是两倍的 log,可以接受。 代码: #include<bits/stdc++.h> #define int long long using namespace std; int T,g,n; vector<int> ans; void dfs(int id,int x){ if(x<=1) return; if(!(x&1)) ans.push_back(id); dfs(id+1,(x-1)/2); if((x-1)/2) ans.push_back(id),ans.push_back(id); } void solve(){ ans.clear(); cin>>n; for(int i=99;i;i--) ans.push_back(i); dfs(1,n); cout<<ans.size()<<"\n"; for(auto x:ans) cout<<x<<" "; } signed main(){ cin>>T>>g; while(T--) solve(); return 0; } P16357 [BalticOI 2026] Blocks 显然当 n 为偶数时就是构造回文串,难点在 n 为奇数的时候。 出现次数为偶数的颜色一律在左右两边对称放,为奇数的话就留下 3 个。 记得要在中间放上一个落单的颜色(或者是从 3 个的颜色里拆一个出来,剩下两个左右对称放) 考虑有解的情况就是剩下若干个出现次数为 3 的颜色,观察到 通过列举小范围数据可以算出通项,具体看代码吧: #include<bits/stdc++.h> using namespace std; #define int long long const int N=1e6+5; int n,k,c[N],ct[N],ans[N]; void solve(){ memset(ct,0,sizeof ct); cin>>n>>k; for(int i=1;i<=n;i++){ cin>>c[i]; ct[c[i]]++; } if(n%2==0){ int ok=1; for(int i=1;i<=k;i++) if(ct[i]&1) ok=0; if(!ok){ cout<<"NO\n"; return; } cout<<"YES\n"; int l=1,r=n; for(int i=1;i<=k;i++){ while(ct[i]>0){ ans[l++]=i; ans[r--]=i; ct[i]-=2; } } for(int i=1;i<=n;i++) cout<<ans[i]<<" \n"[i==n]; return; } int c1=0; for(int i=1;i<=k;i++) if(ct[i]==1) c1++; if(c1>1){ cout<<"NO\n"; return; } int mc=-1; if(c1==1){ for(int i=1;i<=k;i++) if(ct[i]==1){ mc=i; break; } } else{ for(int i=1;i<=k;i++) if(ct[i]&1){ mc=i; break; } } ct[mc]--; vector<int> tp; for(int i=1;i<=k;i++) if(ct[i]&1){ tp.push_back(i); ct[i]-=3; } int t=tp.size(),m=t/2,mid=(n+1)/2; for(int i=1;i<=n;i++) ans[i]=0; ans[mid]=mc; for(int j=1;j<=m;j++){ int col=tp[j-1]; ans[mid+j]=col; ans[mid+j+m]=col; ans[mid-(2*j+m)]=col; } for(int j=1;j<=m;j++){ int col=tp[m+j-1]; ans[mid+(2*m+j)]=col; ans[mid-(m-j+1)]=col; ans[mid-(m+2*j-1)]=col; } int l=1,r=n; for(int i=1;i<=k;i++){ while(ct[i]>0){ while(ans[l]) l++; while(ans[r]) r--; ans[l]=i; ans[r]=i; ct[i]-=2; } } cout<<"YES\n"; for(int i=1;i<=n;i++) cout<<ans[i]<<" \n"[i==n]; } signed main(){ ios::sync_with_stdio(0); cin.tie(0),cout.tie(0); int T; cin>>T; while(T--) solve(); return 0; }
构造专题
笔记