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

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

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

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

做法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
",ans[i]); 
173     return 0;
174 }

 做法2:假设固定右端点,维护log个维上使生成空间变大的最大的l

比做法1快3倍

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef pair<int,int> PII;
  7 typedef pair<ll,ll> Pll;
  8 typedef vector<int> VI;
  9 typedef vector<PII> VII;
 10 typedef pair<ll,int>P;
 11 #define N  510000
 12 #define M  151000
 13 #define fi first
 14 #define se second
 15 #define MP make_pair
 16 #define pi acos(-1)
 17 #define mem(a,b) memset(a,b,sizeof(a))
 18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 20 #define lowbit(x) x&(-x)
 21 #define Rand (rand()*(1<<16)+rand())
 22 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 23 #define ls p<<1
 24 #define rs p<<1|1
 25  
 26 const ll MOD=1e9+7,inv2=(MOD+1)/2;
 27       double eps=1e-6;
 28       ll INF=1e18;
 29       ll inf=5e13;
 30       int dx[4]={-1,1,0,0};
 31       int dy[4]={0,0,-1,1};
 32  
 33 int f[N][31],g[N][31],a[N];
 34  
 35 int read()
 36 {
 37    int v=0,f=1;
 38    char c=getchar();
 39    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 40    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 41    return v*f;
 42 }
 43  
 44 void add(int i,int x)
 45 {
 46     int k=i;
 47     per(j,30,0) f[i][j]=f[i-1][j],g[i][j]=g[i-1][j];
 48     per(j,30,0)
 49      if(x>>j)
 50      {
 51          if(!f[i][j])
 52          {
 53              f[i][j]=x;
 54              g[i][j]=k;
 55              break;
 56          }
 57           else
 58           {
 59               if(k>g[i][j])
 60               {
 61                   swap(k,g[i][j]);
 62                   swap(x,f[i][j]);
 63               }
 64               x^=f[i][j];
 65           }
 66      }
 67 }
 68  
 69 int main()
 70 {
 71     //freopen("1.in","r",stdin);
 72     //freopen("1.out","w",stdout);
 73     //int cas=read();
 74     //while(cas--)
 75     //{
 76         int n=read();
 77         rep(i,1,n)
 78          rep(j,0,30) f[i][j]=g[i][j]=0;
 79         int lastans=0;
 80         rep(i,1,n)
 81         {
 82             a[i]=read();
 83             add(i,a[i]);
 84         }
 85         int m=read();
 86         while(m--)
 87         {
 88             int l=read(),r=read();
 89             lastans=0;
 90             per(i,30,0)
 91             if((lastans^f[r][i])>lastans&&g[r][i]>=l) lastans^=f[r][i];
 92             printf("%d
",lastans);
 93         }
 94  
 95     //}
 96  
 97  
 98  
 99  
100     return 0;
101 }
原文地址:https://www.cnblogs.com/myx12345/p/11438800.html