BZOJ4184 shallot

BZOJ4184 shallot

就是带删除的线性基,考虑对时间分治,就是按时间建线段树,对于一个数,得到他的存在时间区间[l,r],然后对线段树上相应节点记录这个数。最后dfs线段树,在叶子节点求解。

但是我一开始T了,因为我对于每个数[1,n],都重新dfs了一遍,就导致时间复杂度较大。其实可以在dfs中传参线性基。

 1 //考虑对时间分治,就是按时间建线段树,对于一个数,得到他的存在时间区间[l,r],然后对线段树上相应节点记录这个数。最后DFS线段树,在叶子节点求解。
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<vector>
 5 #include<map>
 6 using namespace std;
 7 int n,a[500010];
 8 map<int,int> l,r;
 9 struct xxj
10 {
11     int b[33];
12     void clear(){for(int i=0;i<=32;i++)b[i]=0;}
13     bool ins(int x)
14     {
15         for(int i=31;i>=0;i--)
16         if(x&(1<<i))
17         {
18             if(!b[i]){b[i]=x;break;}
19             else x^=b[i];
20         }
21         if(x)return 1;
22         else return 0;
23     }
24     int findmax()
25     {
26         int ans=0;
27         for(int i=31;i>=0;i--)
28         ans=max(ans,ans^b[i]);
29         return ans;
30     }
31 }ans[500010];
32 struct tree
33 {
34     int l,r;
35     vector<int> sum;
36     #define l(x) tr[x].l
37     #define r(x) tr[x].r
38     #define sum(x) tr[x].sum 
39 }tr[3000010];
40 int cnt,root;
41 
42 int build(int L,int R)
43 {
44     int now=++cnt;
45     if(L==R)return cnt;
46     int mid=(L+R)>>1;
47     l(now)=build(L,mid);
48     r(now)=build(mid+1,R);
49     return now;
50 }
51 void add(int l,int r,int L,int R,int x,int z)
52 {
53     if(L==R){sum(x).push_back(z);return;}
54     if(L>=l&&R<=r){sum(x).push_back(z);return;}
55     int mid=(L+R)>>1;
56     if(l<=mid)add(l,r,L,mid,l(x),z);
57     if(r> mid)add(l,r,mid+1,R,r(x),z);
58 }
59 void dfs(int x,int L,int R)
60 {
61     for(int i=0;i<sum(x).size();i++)
62         for(int j=L;j<=R;j++)
63         ans[j].ins(sum(x)[i]);
64     if(L==R)return;
65     int mid=(L+R)>>1;
66     dfs(l(x),L,mid);
67     dfs(r(x),mid+1,R);
68 }
69 signed main()
70 {
71 //    freopen("in.txt","r",stdin);
72 
73     cin>>n;
74     for(int i=1;i<=n;i++)    
75     {            
76         cin>>a[i];
77         if(a[i]<0)r[-a[i]]=i-1;
78         else   l[a[i]]=i;
79     }
80     root=build(1,n);
81     for(int i=1;i<=n;i++)
82     if(a[i]>0)
83         add(l[a[i]],r[a[i]]==0?n:r[a[i]],1,n,root,a[i]);    
84     dfs(root,1,n);
85     for(int i=1;i<=n;i++)
86         printf("%d
",ans[i].findmax());
87 }
完整代码

 

 

原文地址:https://www.cnblogs.com/Al-Ca/p/11240185.html