【GDKOI2016Day1T1-魔卡少女】【拆位】線段樹維護區間內所有連續子區間的異或和


題意:給出N個數,M個操作。操作有修改和詢問兩種,每次修改將一個數改成另一個數,每次詢問一個區間的所有連續子區間的異或和。n,m<=100000,ai<=1000

題解:

 

當年(其實也就是今年)做不出來的題。。D1T1啊。。。

因為ai<=1000,我們可以拆位處理。拆成10個二進制位,每位開1棵線段樹。

對於每個節點,維護:

d:這段區間的異或和

L[0],L[1]:子區間一定從左端點開始,異或和為0,1的子區間分別有多少個

R[0],R[1]:子區間一定從右端點開始,異或和為0,1的子區間分別有多少個

s[0],s[1]:異或和為0,1的子區間分別有多少個

然后重點就是合並啦。

 1 node upd(int ind,int tmp,node lc,node rc)  2 {  3     int dl=lc.d,dr=rc.d;  4  node x;  5     if(tmp!=0) x=t[ind][tmp];  6     x.d=lc.d^rc.d;  7     x.L[0]=(lc.L[0]+rc.L[(dl==0) ? 0:1])%mod;  8     x.L[1]=(lc.L[1]+rc.L[(dl==0) ? 1:0])%mod;  9     x.R[0]=(rc.R[0]+lc.R[(dr==0) ? 0:1])%mod; 10     x.R[1]=(rc.R[1]+lc.R[(dr==0) ? 1:0])%mod; 11     x.s[0]=(lc.s[0]+rc.s[0]+(lc.R[0]*rc.L[0])%mod+(lc.R[1]*rc.L[1])%mod)%mod; 12     x.s[1]=(lc.s[1]+rc.s[1]+(lc.R[0]*rc.L[1])%mod+(lc.R[1]*rc.L[0])%mod)%mod; 13     return x; 14 }

我打成node形式。。因為最后查詢的時候有多個區間也要合並。。

 

代碼:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<algorithm>
 7 using namespace std;  8 
 9 typedef long long LL;  10 const int N=100010;  11 const LL mod=100000007;  12 struct node{  13     int l,r,lc,rc,d;  14     LL L[2],R[2],s[2];  15     //L:從左開始  16     //R:從右開始  17     //s:總答案
 18 }t[10][2*N];  19 char c[10];  20 int n,m,tl,a[N][10];  21 LL bit[15];  22 
 23 node upd(int ind,int tmp,node lc,node rc)  24 {  25     int dl=lc.d,dr=rc.d;  26  node x;  27     if(tmp!=0) x=t[ind][tmp];  28     x.d=lc.d^rc.d;  29     x.L[0]=(lc.L[0]+rc.L[(dl==0) ? 0:1])%mod;  30     x.L[1]=(lc.L[1]+rc.L[(dl==0) ? 1:0])%mod;  31     x.R[0]=(rc.R[0]+lc.R[(dr==0) ? 0:1])%mod;  32     x.R[1]=(rc.R[1]+lc.R[(dr==0) ? 1:0])%mod;  33     x.s[0]=(lc.s[0]+rc.s[0]+(lc.R[0]*rc.L[0])%mod+(lc.R[1]*rc.L[1])%mod)%mod;  34     x.s[1]=(lc.s[1]+rc.s[1]+(lc.R[0]*rc.L[1])%mod+(lc.R[1]*rc.L[0])%mod)%mod;  35     return x;  36 }  37 
 38 int bt(int ind,int l,int r)  39 {  40     int x=++tl;  41     t[ind][x].l=l;t[ind][x].r=r;  42     t[ind][x].lc=t[ind][x].rc=0;  43     t[ind][x].d=0;  44     memset(t[ind][x].L,0,sizeof(t[ind][x].L));  45     memset(t[ind][x].R,0,sizeof(t[ind][x].R));  46     memset(t[ind][x].s,0,sizeof(t[ind][x].s));  47     if(l<r)  48  {  49         int mid=(l+r)/2;  50         t[ind][x].lc=bt(ind,l,mid);  51         t[ind][x].rc=bt(ind,mid+1,r);  52         int lc=t[ind][x].lc,rc=t[ind][x].rc;  53         t[ind][x]=upd(ind,x,t[ind][lc],t[ind][rc]);  54  }  55     else 
 56  {  57         int d=a[l][ind];  58         t[ind][x].d=d;  59         t[ind][x].L[d]=t[ind][x].R[d]=t[ind][x].s[d]=1;  60  }  61     return x;  62 }  63 
 64 void change(int ind,int x,int p,int d)  65 {  66     if(t[ind][x].l==t[ind][x].r)  67  {  68         t[ind][x].d=d;  69         t[ind][x].L[d]=t[ind][x].R[d]=t[ind][x].s[d]=1;  70         t[ind][x].L[d^1]=t[ind][x].R[d^1]=t[ind][x].s[d^1]=0;  71         return ;  72  }  73     int lc=t[ind][x].lc,rc=t[ind][x].rc,mid=(t[ind][x].l+t[ind][x].r)/2;  74     if(p<=mid) change(ind,lc,p,d);  75     else change(ind,rc,p,d);  76     t[ind][x]=upd(ind,x,t[ind][lc],t[ind][rc]);  77 }  78 
 79 node query(int ind,int x,int l,int r)  80 {  81     if(t[ind][x].l==l && t[ind][x].r==r) return t[ind][x];  82     int lc=t[ind][x].lc,rc=t[ind][x].rc,mid=(t[ind][x].l+t[ind][x].r)/2;  83     if(r<=mid) return query(ind,lc,l,r);  84     else if(l>mid) return query(ind,rc,l,r);  85     else
 86  {  87         node a0=query(ind,lc,l,mid);  88         node a1=query(ind,rc,mid+1,r);  89         return upd(0,0,a0,a1);  90  }  91 }  92 
 93 void output(int ind,int x)  94 {  95     int lc=t[ind][x].lc,rc=t[ind][x].rc;  96     printf("l=%d r=%d d=%d l0=%lld l1=%lld r0=%lld r1=%lld s0=%lld s1=%lld\n",t[ind][x].l,t[ind][x].r,t[ind][x].d,t[ind][x].L[0],t[ind][x].L[1],t[ind][x].R[0],t[ind][x].R[1],t[ind][x].s[0],t[ind][x].s[1]);  97     if(lc) output(ind,lc);  98     if(rc) output(ind,rc);  99 } 100 
101 int main() 102 { 103     freopen("a.in","r",stdin); 104     freopen("me.out","w",stdout); 105     // freopen("cardcaptor.in","r",stdin); 106     // freopen("cardcaptor.out","w",stdout);
107     scanf("%d",&n); 108     int x,ind;node now; 109     bit[0]=1; 110     for(int i=1;i<=10;i++) bit[i]=bit[i-1]*2; 111     memset(a,0,sizeof(a)); 112     for(int i=1;i<=n;i++) 113  { 114         scanf("%d",&x); 115         ind=0; 116         while(x) 117  { 118             a[i][ind]=x%2; 119             x/=2; 120             ind++; 121  } 122  } 123     scanf("%d",&m); 124     for(int i=0;i<10;i++) {tl=0;bt(i,1,n);} 125     for(int i=1;i<=m;i++) 126  { 127         scanf("%s",c); 128         if(c[0]=='Q') 129  { 130             int l,r;LL ans=0; 131             scanf("%d%d",&l,&r); 132             for(int j=0;j<10;j++) 133  { 134                 now=query(j,1,l,r); 135                 ans=(ans+(bit[j]*now.s[1])%mod)%mod; 136  } 137             printf("%lld\n",ans); 138  } 139         else
140  { 141             int ind=0,p,d; 142             scanf("%d%d",&p,&d); 143             while(d) 144  { 145                 change(ind,1,p,d%2); 146                 d/=2; 147                 ind++; 148  } 149             for(int j=ind;j<10;j++) change(j,1,p,0); 150  } 151  } 152     return 0; 153 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM