线性基求交(线段树)--牛客第四场(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 }