线性基求交(线段树)--牛客第四场(xor)

题意:

给你n个基,q个询问,每个询问问你能不能 l~r 的所有基都能表示 x 。

思路:

建一颗线性基的线段树,up就是求交的过程,按照线段树区间查询的方法进行check就可以了。

  1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0);
  2 #include <cstdio>//sprintf islower isupper
  3 #include <cstdlib>//malloc  exit strcat itoa system("cls")
  4 #include <iostream>//pair
  5 #include <fstream>
  6 #include <bitset>
  7 //#include <map>
  8 //#include<unordered_map>
  9 #include <vector>
 10 #include <stack>
 11 #include <set>
 12 #include <string.h>//strstr substr
 13 #include <string>
 14 #include <time.h>//srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
 15 #include <cmath>
 16 #include <deque>
 17 #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
 18 #include <vector>//emplace_back
 19 //#include <math.h>
 20 //#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
 21 #include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
 22 using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
 23 #define fo(a,b,c) for(register int a=b;a<=c;++a)
 24 #define fr(a,b,c) for(register int a=b;a>=c;--a)
 25 #define mem(a,b) memset(a,b,sizeof(a))
 26 #define pr printf
 27 #define sc scanf
 28 void swapp(int &a,int &b);
 29 double fabss(double a);
 30 int maxx(int a,int b);
 31 int minn(int a,int b);
 32 int Del_bit_1(int n);
 33 int lowbit(int n);
 34 int abss(int a);
 35 //const long long INF=(1LL<<60);
 36 const double E=2.718281828;
 37 const double PI=acos(-1.0);
 38 const int inf=(1<<29);
 39 const double ESP=1e-9;
 40 const int mod=(int)1e9+7;
 41 const int N=(int)1e6+10;
 42  
 43 struct node
 44 {
 45     long long base[35];
 46  
 47     void Init()
 48     {
 49         for(int i=0;i<35;++i)
 50             base[i]=0;
 51     }
 52  
 53     bool check(long long x)
 54     {
 55         for(int i=31;i>=0;--i)
 56         {
 57             if(x&(1LL<<i))
 58             {
 59                 if(!base[i])return 0;
 60                 else x^=base[i];
 61             }
 62         }
 63         return 1;
 64     }
 65  
 66     void Insert(long long x)
 67     {
 68         for(int i=31;i>=0;--i)
 69         {
 70             if(x>>i&1)
 71             {
 72                 if(base[i])
 73                     x^=base[i];
 74                 else
 75                 {
 76                     base[i]=x;
 77                     break;
 78                 }
 79             }
 80         }
 81     }
 82 }BASE[N<<2],temp,v;
 83  
 84 void merge(const node &a,node &b,node &ans)
 85 {
 86     temp=v=a;
 87     fo(i,0,31)
 88     {
 89         if(b.base[i])
 90         {
 91             long long x=b.base[i],now=0;
 92             int g=0;
 93             for(int j=31;j>=0;j--)
 94             {
 95                 if(x>>j&1)
 96                 {
 97                     if(!temp.base[j])
 98                     {
 99                         g=1;
100                         temp.base[j]=x;
101                         v.base[j]=now;
102                         break;
103                     }
104                     x^=temp.base[j];now^=v.base[j];
105                 }
106             }
107             if(!g)
108                 ans.Insert(now);
109         }
110     }
111 }
112  
113 void up(int rt)
114 {
115     merge(BASE[rt<<1],BASE[rt<<1|1],BASE[rt]);
116 }
117 void Build(int l,int r,int rt)
118 {
119     if(l==r)
120     {
121         int sz;
122         long long x;
123         sc("%d",&sz);
124         fo(i,1,sz)
125         {
126             sc("%lld",&x);
127             BASE[rt].Insert(x);
128         }
129         return;
130     }
131     int mid=(l+r)>>1;
132  
133     Build(l,mid,rt<<1);
134     Build(mid+1,r,rt<<1|1);
135     up(rt);
136 }
137 bool Query(int L,int R,long long V,int l,int r,int rt)
138 {
139     if(L<=l&&r<=R)
140         return BASE[rt].check(V);
141     int mid=(l+r)>>1;
142  
143     if(L<=mid&&!Query(L,R,V,l,mid,rt<<1))
144         return 0;
145     if(R>mid&&!Query(L,R,V,mid+1,r,rt<<1|1))
146         return 0;
147     return 1;
148 }
149  
150 int main()
151 {
152     int n,m;
153     sc("%d%d",&n,&m);
154  
155     Build(1,n,1);
156     fo(i,1,m)
157     {
158         int l,r;
159         long long x;
160         sc("%d%d%lld",&l,&r,&x);
161         if(Query(l,r,x,1,n,1))
162             pr("YES\n");
163         else
164             pr("NO\n");
165     }
166     return 0;
167 }
168  
169 /**************************************************************************************/
170  
171 int maxx(int a,int b)
172 {
173     return a>b?a:b;
174 }
175  
176 void swapp(int &a,int &b)
177 {
178     a^=b^=a^=b;
179 }
180  
181 int lowbit(int n)
182 {
183     return n&(-n);
184 }
185  
186 int Del_bit_1(int n)
187 {
188     return n&(n-1);
189 }
190  
191 int abss(int a)
192 {
193     return a>0?a:-a;
194 }
195  
196 double fabss(double a)
197 {
198     return a>0?a:-a;
199 }
200  
201 int minn(int a,int b)
202 {
203     return a<b?a:b;
204 }

猜你喜欢

转载自www.cnblogs.com/--HPY-7m/p/11437183.html