初见线段树分治
(对我来说可不是什么经典题=。=)
把时间轴建出来一棵线段树,然后在对应的区间上打标记,最后把整棵树DFS一遍,到叶节点输出答案即可
(把最终答案开成全局的了调了半天
1 #include<cstdio> 2 #include<bitset> 3 #include<vector> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 const int N=505,M=1005; 8 int n,m,s,t1,t2,len,lst[N]; 9 char str[M]; bitset<M> lbt[N],rd; 10 vector<bitset<M> > ve[4*M]; 11 struct a 12 { 13 bitset<M> bit[M]; 14 void Set(bitset<M> bt) 15 { 16 for(int i=1000;~i;i--) 17 if(bt[i]) bt^=bit[i]; 18 for(int i=1000;~i;i--) 19 if(bt[i]&&!bit[i].any()) 20 {bit[i]=bt; break;} 21 } 22 void Output() 23 { 24 bitset<M> outp; outp.reset(); 25 for(int i=1000;~i;i--) 26 if(!outp[i]&&bit[i].any()) 27 outp^=bit[i]; 28 bool b=false; 29 for(int i=1000;~i;i--) 30 if(outp[i]) 31 { 32 b=true; 33 for(int j=i;~j;j--) 34 printf("%d",outp[j]?1:0); 35 break; 36 } 37 if(!b) printf("0"); puts(""); 38 } 39 }sb; 40 void Add(int nde,int l,int r,int ll,int rr,bitset<M> bt) 41 { 42 if(l>rr||r<ll) 43 return ; 44 else if(l>=ll&&r<=rr) 45 ve[nde].push_back(bt); 46 else 47 { 48 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; 49 Add(ls,l,mid,ll,rr,bt),Add(rs,mid+1,r,ll,rr,bt); 50 } 51 } 52 void Getans(int nde,int l,int r,a sb) 53 { 54 int siz=ve[nde].size(); 55 for(int i=0;i<siz;i++) 56 sb.Set(ve[nde][i]); 57 if(l==r) 58 sb.Output(); 59 else 60 { 61 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; 62 Getans(ls,l,mid,sb),Getans(rs,mid+1,r,sb); 63 } 64 } 65 int main() 66 { 67 scanf("%d%d%d",&s,&n,&m); 68 for(int i=1;i<=m;i++) 69 { 70 scanf("%d%d",&t1,&t2); 71 scanf("%s",str),len=strlen(str); 72 if(t1!=t2) 73 { 74 rd.reset(); 75 for(int j=0;j<len;j++) 76 rd[j]=str[len-j-1]-'0'; 77 if(lst[t1]) Add(1,1,m,lst[t1],i-1,lbt[t1]); 78 if(lst[t2]) Add(1,1,m,lst[t2],i-1,lbt[t2]); 79 lst[t1]=lst[t2]=i,lbt[t1]^=rd,lbt[t2]^=rd; 80 } 81 } 82 for(int i=1;i<=n;i++) 83 if(lst[i]) Add(1,1,m,lst[i],m,lbt[i]); 84 Getans(1,1,m,sb); 85 return 0; 86 }