社区讨论
85分求助
P9746 「KDOI-06-S」合并序列参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @lz8f3c82
- 此快照首次捕获于
- 2024/07/30 20:51 2 年前
- 此快照最后确认于
- 2024/07/30 22:00 2 年前
CPP
#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
int T;
int n;
int a[538];
int xor_[538][538];//每一个区间的值
struct g{
int l,r;
}g1[538][538];//g1[l][k] 左端点大于等于 l,权值为 k,求最小右端点(必须是合法区间)
struct h{
int l1,r1;
int l2,r2;
}h1[538][538];//h1[l][k] 左端点为 l, [l,a]、[b,c]异或值为k 且两端区间合法
struct f{
int l1,r1;
int l2,r2;
int l3,r3;
}dp[538][538];
bool rev[538][538];
int p[538];
struct ans{
int l1,r1;
int l2,r2;
int l3,r3;
}ans1[538];
int ptr=0;
void init(){
ptr=0;
for(int i=0;i<=530;i++){
p[i]=i;
for(int j=0;j<=530;j++){
g1[i][j]=(g){-1,-1};
h1[i][j]=(h){-1,-1,-1,-1};
dp[i][j]=(f){-1,-1,-1,-1,-1,-1};
rev[i][j]=false;
}
}
}
inline void dfs(int l,int r){
// cout<<l<<' '<<r<<endl;
if(l==r) return;
int l1=dp[l][r].l1;
int l2=dp[l][r].l2;
int l3=dp[l][r].l3;
int r1=dp[l][r].r1;
int r2=dp[l][r].r2;
int r3=dp[l][r].r3;
dfs(l1,r1);
dfs(l2,r2);
dfs(l3,r3);
ans1[++ptr]=(ans){l1,r1,l2,r2,l3,r3};
}
void solve(){
init();
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
xor_[i][i]=a[i];
rev[i][i]=true;
int xor1=xor_[i][i];
g1[i][xor1]=(g){i,i};
// cout<<i<<' '<<xor1<<' '<<g1[i][xor1].l<<' '<<g1[i][xor1].r<<endl;
}
// cout<<g1[5][5].r<<endl;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
xor_[i][j]=(xor_[i][j-1]^a[j]);
// cout<<i<<' '<<j<<' '<<xor_[i][j]<<endl;
}
// cout<<endl;
}
for(register int l=n;l>=1;l--){
for(int xor6=0;xor6<=530;xor6++){
if((g1[l][xor6].l==-1&&g1[l+1][xor6].l!=-1)||(g1[l][xor6].r>g1[l+1][xor6].r&&g1[l+1][xor6].r!=-1)){
g1[l][xor6].l=g1[l+1][xor6].l;
g1[l][xor6].r=g1[l+1][xor6].r;
// cout<<l<<' '<<xor6<<' '<<g1[l][xor6].l<<' '<<g1[l][xor6].r<<endl;
}
}
for(register int r=l;r<=n;r++){
int xor4=xor_[l][r];
for(register int k=l+1;k<=r;k++){
int xor3=xor_[k+1][r];//第三个区间的异或和
int l1_=h1[l][xor3].l1;
int l2_=h1[l][xor3].l2;
int r1_=h1[l][xor3].r1;
int r2_=h1[l][xor3].r2;
int l3_=k+1;
int r3_=r;
if(r2_!=-1&&r2_<=k&&rev[l3_][r3_]==true&&rev[l1_][r1_]&&rev[l2_][r2_]){
rev[l][r]=true;
dp[l][r]=(f){l1_,r1_,l2_,r2_,l3_,r3_};
// cout<<"a "<<l1_<<' '<<r1_<<' '<<l2_<<' '<<r2_<<' '<<l3_<<" "<<r3_<<endl;
if(g1[l][xor4].l==-1||g1[l][xor4].r>r){
g1[l][xor4]=(g){l,r};
// cout<<"g1"<<' '<<l<<' '<<xor4<<' '<<l<<' '<<r<<endl;
}
}
// if(rev[l][r]) break;
}
if(rev[l][r]==true){
for(int xor5=0;xor5<=515;xor5++){
int l1=g1[r+1][xor5].l;
int r1=g1[r+1][xor5].r;
int k=(xor4^xor5);
if((h1[l][k].l1==-1||h1[l][k].r2>r1)&&l1!=-1){
h1[l][k]=(h){l,r,l1,r1};
// cout<<"h1"<<' '<<l<<' '<<k<<' '<<l<<' '<<r<<' '<<l1<<' '<<r1<<endl;
}
}
}
}
for(int xor6=0;xor6<=515;xor6++){
if((g1[l][xor6].l==-1&&g1[l+1][xor6].l!=-1)||(g1[l][xor6].r>g1[l+1][xor6].r&&g1[l+1][xor6].r!=-1)){
g1[l][xor6].l=g1[l+1][xor6].l;
g1[l][xor6].r=g1[l+1][xor6].r;
// cout<<l<<' '<<xor6<<' '<<g1[l][xor6].l<<' '<<g1[l][xor6].r<<endl;
}
}
}
if(!rev[1][n]){
puts("Shuiniao");
}
else{
puts("Huoyu");
if(n>1) dfs(1,n);
cout<<ptr<<endl;
for(int i=1;i<=ptr;i++){
int l1=ans1[i].l1;
int l2=ans1[i].l2;
int l3=ans1[i].l3;
int r1=ans1[i].r1;
int r2=ans1[i].r2;
int r3=ans1[i].r3;
cout<<p[l1]<<' '<<p[l2]<<' '<<p[l3]<<endl;
// cout<<l1<<' '<<r1<<' '<<l2<<' '<<r2<<' '<<l3<<' '<<r3<<endl;
for(int j=l1;j<=r3;j++){
p[j]=p[l1];
}
for(int j=r3+1;j<=n;j++){
p[j]=p[j-1]+1;
}
// for(int j=1;j<=n;j++){
// cout<<p[j]<<' ';
// }
// cout<<endl<<endl;
}
}
return;
}
int main(){
// freopen("merge.in","r",stdin);
// freopen("merge.out","w",stdout);
scanf("%d",&T);
while(T--){
solve();
}
return 0;
}
Daniel_lele
回复
共 0 条回复,欢迎继续交流。
正在加载回复...