日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P5607-[Ynoi2013]无力回天NOI2017【线性基,线段树,树状数组】

發布時間:2023/12/3 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P5607-[Ynoi2013]无力回天NOI2017【线性基,线段树,树状数组】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/P5607


題目大意

nnn個數字的序列,mmm次操作

  • 區間[l,r][l,r][l,r]異或上一個值vvv
  • 詢問區間[l,r][l,r][l,r]中選出一些數來異或的最大異或和

  • 解題思路

    最大異或和的話只能是線性基了,但是線性基的區間修改又不能通過打標記的方法。

    不能區間修改就轉單點修改,我們定義一個序列bi=aixorai?1b_i=a_i\ xor\ a_{i-1}bi?=ai??xor?ai?1?。這樣修改的時候就可以單點進行修改了。

    但是這樣好像會影響我們的查詢操作,考慮查詢區間[l,r][l,r][l,r]的時候,我們會選出若干個前綴來進行操作,被異或多次的區間會抵消掉一些,如果選擇了bxb_xbx?就可以理解為選擇了ax?1xoraxa_{x-1}\ xor\ a_{x}ax?1??xor?ax?

    但是會發現b1~lb_{1\sim l}b1l?也就是ala_lal?可能會被異或很多次,其實可以把bl+1~r∪alb_{l+1\sim r}\cup a_lbl+1r?al?的線性基拿出來跑就是答案了。因為如果在[l+1,r][l+1,r][l+1,r]這個范圍無論選擇了奇偶個都可以用ala_lal?來決定前面區間的異或次數。

    ala_lal?的話我們再維護一個樹狀數組來查詢就好了,注意一下細節就行了

    時間復雜度O((n+m)log?nlog?2w)O((n+m)\log n\log^2 w)O((n+m)lognlog2w)


    code

    #include<cstdio> #include<cstring> #include<algorithm> #define lowbit(x) (x&-x) using namespace std; const int N=5e4+10; struct xxj{int d[32];void init(){memset(d,0,sizeof(d));}void Insert(int x){for(int i=30;i>=0;i--)if((x>>i)&1){if(d[i])x^=d[i];else{d[i]=x;return;}}return;}int Query(int x){for(int i=30;i>=0;i--)if((x^d[i])>x)x^=d[i];return x;} }c,w[N<<2],ans; int n,m,a[N],t[N]; void Add(xxj &a,xxj &b){for(int i=0;i<=30;i++)if(b.d[i])a.Insert(b.d[i]);return; } void Change(int x,int L,int R,int pos,int val){if(L==R){w[x].init();a[L]^=val;w[x].Insert(a[L]);return;}int mid=(L+R)>>1;if(pos<=mid)Change(x*2,L,mid,pos,val);else Change(x*2+1,mid+1,R,pos,val);w[x]=w[x*2];Add(w[x],w[x*2+1]);return; } void Ask(int x,int L,int R,int l,int r){if(L==l&&R==r){Add(ans,w[x]);return;}int mid=(L+R)>>1;if(r<=mid)Ask(x*2,L,mid,l,r);else if(l>mid)Ask(x*2+1,mid+1,R,l,r);else Ask(x*2,L,mid,l,mid),Ask(x*2+1,mid+1,R,mid+1,r);return; } void Change(int x,int val){while(x<=n){t[x]^=val;x+=lowbit(x);}return; } int Ask(int x){int ans=0;while(x){ans^=t[x];x-=lowbit(x);}return ans; } int main() {scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&a[i]);for(int i=n;i>=1;i--){int p=a[i]^a[i-1];a[i]=0;Change(1,1,n,i,p);Change(i,p);}while(m--){int op,l,r,x;scanf("%d%d%d%d",&op,&l,&r,&x);if(op==1){Change(l,x);Change(r+1,x);Change(1,1,n,l,x);if(r<n)Change(1,1,n,r+1,x);}else{ans.init();if(l<r)Ask(1,1,n,l+1,r);int mx=ans.Query(x);mx=max(mx,ans.Query(x^Ask(l)));printf("%d\n",mx);}}return 0; }

    總結

    以上是生活随笔為你收集整理的P5607-[Ynoi2013]无力回天NOI2017【线性基,线段树,树状数组】的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。