【CF1100F】Ivan and Burgers(线性基,分治)

题意:给定n个数,每个数为c[i],有q个询问,每次询问从第l个到第r个数字的最大xor和

n,q<=5e5,c[i]<=1e6,时限3s

思路:直接线段树维护区间线性基是3个log

做法1:因为不是强制在线把询问分治能降到2个log

  1 #include<bits/stdc++.h>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<cmath>
  6 #include<iostream>
  7 #include<algorithm>
  8 #include<map>
  9 #include<set>
 10 #include<queue>
 11 #include<vector>
 12 #include<bitset>
 13 using namespace std;
 14 typedef long long ll;
 15 typedef unsigned int uint;
 16 typedef unsigned long long ull;
 17 typedef pair<int,int> PII;
 18 typedef vector<int> VI;
 19 typedef set<int>::iterator iter;
 20 #define fi first
 21 #define se second 
 22 #define MP make_pair
 23 #define mem0(a) memset(a,0,sizeof(a))
 24 #define N      510000
 25 #define M      15
 26 #define MOD 1000000007
 27 #define eps 1e-10
 28 #define pi     acos(-1)
 29 #define oo     1e9
 30  
 31 int read()
 32 { 
 33    int v=0,f=1;
 34    char c=getchar();
 35    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 36    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 37    return v*f;
 38 }
 39  
 40 struct base
 41 {
 42     //ll d[20],p[20];
 43     int d[20];
 44     int cnt;
 45     
 46     base()
 47     {
 48         memset(d,0,sizeof(d));
 49         //memset(p,0,sizeof(p));
 50         cnt=0;
 51     }    
 52     bool insert(int val)
 53     {
 54         if(val==0) return 0; 
 55         for(int i=20;i>=0;i--)
 56          if((val>>i)&1)
 57             {
 58                 if(!d[i])
 59                 {
 60                     d[i]=val;
 61                     break;
 62                 }
 63                 val^=d[i];
 64             }
 65         return val>0;
 66     }
 67     int query_max()
 68     {
 69         int ret=0;
 70         for(int i=20;i>=0;i--) ret=max(ret,ret^d[i]);
 71         return ret;
 72     }
 73     int query_min()
 74     {
 75         for(int i=0;i<=20;i++)
 76          if(d[i]) return d[i];
 77         return 0;
 78     }
 79     /*void rebuild()
 80     {
 81         for(int i=20;i>=0;i--)
 82          for(int j=i-1;j>=0;j--)
 83           if((d[i]>>j)&1) d[i]^=d[j];
 84         for(int i=0;i<=20;i++)
 85          if(d[i]) p[cnt++]=d[i];
 86     }
 87     ll kthquery(ll k)
 88     {
 89         int ret=0;
 90         if(k>=(1LL<<cnt)) return -1;
 91         for(int i=20;i>=0;i--)
 92          if((k>>i)&1) ret^=p[i];
 93         return ret;
 94     }*/
 95     
 96     base operator+(const base&_A)const 
 97     {
 98         base ret=*this;
 99         for(int i=20;i>=0;i--) 
100          if(_A.d[i]) ret.insert(_A.d[i]);
101         return ret;
102     }
103 }t[N],b;
104  
105 struct arr
106 {
107     int x,y,id;
108 }q[N],c[N];
109  
110 int a[N],ans[N];
111  
112 /*base merge(const base &n1,const base &n2)
113 {
114     base ret=n1;
115     for(int i=20;i>=0;i--)
116      if(n2.d[i]) ret.insert(n1.d[i]);
117     return ret;
118 }*/
119  
120 void solve(int l,int r,int x,int y)
121 {
122     if(l==r)
123     {
124         for(int i=x;i<=y;i++) ans[q[i].id]=a[l];
125         return;
126     }
127     if(x>y) return;
128     int mid=(l+r)>>1;
129     memset(b.d,0,sizeof(b.d));
130     for(int i=mid;i>=l;i--)
131     {
132         b.insert(a[i]);
133         for(int j=0;j<=20;j++) t[i].d[j]=b.d[j];
134     }
135     memset(b.d,0,sizeof(b.d));
136     for(int i=mid+1;i<=r;i++)
137     {
138         b.insert(a[i]);
139         for(int j=0;j<=20;j++) t[i].d[j]=b.d[j];
140     }
141     int l1=x,r1=y;
142     for(int i=x;i<=y;i++)
143     {
144         if(q[i].y<=mid) c[l1++]=q[i];
145          else if(q[i].x>mid) c[r1--]=q[i];
146           else
147           {
148                   base tmp=t[q[i].x]+t[q[i].y];
149                 ans[q[i].id]=tmp.query_max();
150           }    
151     }
152     for(int i=x;i<l1;i++) q[i]=c[i];
153     for(int i=r1+1;i<=y;i++) q[i]=c[i];
154     solve(l,mid,x,l1-1);
155     solve(mid+1,r,r1+1,y);
156 }
157  
158 int main()
159 {
160     //freopen("cf1100f.in","r",stdin);
161     //freopen("cf1100f.out","w",stdout); 
162     int n,m;
163     scanf("%d",&n);
164     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
165     scanf("%d",&m);
166     for(int i=1;i<=m;i++)
167     {
168         scanf("%d%d",&q[i].x,&q[i].y);
169         q[i].id=i;
170     }
171     solve(1,n,1,m);
172     for(int i=1;i<=m;i++) printf("%d\n",ans[i]); 
173     return 0;
174 }

猜你喜欢

转载自www.cnblogs.com/myx12345/p/11438800.html
今日推荐