1 条题解
-
0
自动搬运
来自洛谷,原作者为

luanyanjia
菜 -我ら是个と大に傻む逼なり-搬运于
2025-08-24 23:18:15,当前版本为作者最后更新于2025-06-14 18:45:51,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
AI 做不出这种题吗,挺有道理的。
最开始做这个题的时候,我就想过如果区间异或上一个数时,如果简单地将线性基内的元素全部异或,那么只有偶数个元素的集合搞出来是正确的,所以直接做是不可行的,但在这个题上却刚刚好。
先用带时间戳的线性基把询问区间的线性基搞出来(要离线扫描线)。
对于第二种询问,我们将线性基中每一个数都异或 , 也异或上 ,这样因为要贪心取最大值,所以最后的方案一定是取了偶数个数。否则答案不带 一定更小。
对于第一种询问,我们同样地做,这样奇数个数的方案异或出来的值带有 ,所以一定不合法,求答案只需按位贪心,假设前面几位都顶到了上界,此时异或出来的值是确定的,然后分讨计算即可。最后答案要乘上 ( 是线性基的元素个数)。
分讨的部分可以看看代码。
const int V=60; struct Linear_Basis{ int b[V+5],tm[V+5]; inline void Insert(int x,int t,int st){ for(int i=st;i>=0;i--){ if((x>>i)&1){ if(b[i]){ if(tm[i]<t){ Insert(x^b[i],tm[i],i-1); b[i]=x;tm[i]=t; break; } else x^=b[i]; }else{ b[i]=x;tm[i]=t; break; } } } } inline int Query(int x,int v){ int now=v; for(int i=30;i>=0;i--) if(tm[i]>=x&&!(now>>i&1)) now^=b[i]; return now; } int c[60]; inline int Get(int l,int r,int x){ int cnt=0,ans=0,now=0; c[0]=(b[0]!=0)&&tm[0]>=l; for(int i=1;i<=30;i++)c[i]=c[i-1]+((b[i]!=0)&&tm[i]>=l); for(int i=30;i>=0;i--)if(tm[i]>=l&&b[i])++cnt; for(int i=30;;i--){ if(i==-1){ if(now<=x)Add(ans,1); break; } if(x>>i&1){ if((now>>i&1)&&(b[i]&&tm[i]>=l))Add(ans,i?m2[c[i-1]]:1); if(!(now>>i&1)){ if(b[i]&&tm[i]>=l){ now^=b[i]; if(i)Add(ans,m2[c[i-1]]); else Add(ans,1); }else{ if(i)Add(ans,m2[c[i-1]]); else Add(ans,1); break; } } }else{ if(now>>i&1){ if(!b[i]||tm[i]<l)break; else if(tm[i]>=l)now^=b[i]; } } } ans=1ll*ans*m2[r-l+1-cnt]%mod; return ans; } inline void Clear(){ memset(b,0,sizeof b); memset(tm,0,sizeof tm); } }LB; inline void Solve(){ rd(n,q); for(int i=1;i<=n;i++)rd(a[i]); for(int i=1;i<=q;i++){ int op,l,r,x;rd(op,l,r,x); vec[r].emplace_back(op,l,x,i); } LB.Clear(); for(int i=1;i<=n;i++){ LB.Insert(a[i]^(1<<30),i,30); for(auto[op,l,x,id]:vec[i]){ if(op==1){ ans[id]=LB.Query(l,x^(1<<30))^(1<<30); }else{ ans[id]=LB.Get(l,i,x); } } } for(int i=1;i<=n;i++)vec[i].clear(); for(int i=1;i<=q;i++)printf("%d\n",ans[i]); } signed main(){ m2[0]=1; for(int i=1;i<=500000;i++)m2[i]=m2[i-1]*2%mod; rd(T); while(T--)Solve(); return 0; }
- 1
信息
- ID
- 11728
- 时间
- 1500ms
- 内存
- 512MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者