码迷,mamicode.com
首页 > 其他好文 > 详细

Iahub and Xors Codeforces - 341D

时间:2018-05-19 17:10:44      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:==   space   线段   数列   turn   oid   线段树   lld   code   

二维线段树被卡M+T。。。于是去学二维树状数组区间更新区间查询

树状数组维护数列区间xor的修改、删除(就是把原问题改成一维):

以下p*i实际都指i个p相xor,即(i&1)*p
a表示原数列
d[i]表示a[i]^a[i-1],e[i]=d[i]*i
getd(x)和gete(x)分别表示对d/e求前x个元素的前缀xor
用树状数组维护e[i]和d[i]的前缀xor
区间更新[l,r],x:d[l]^=x,d[r+1]^=x,e[l]^=l*x,e[r+1]^=(r+1)*x
区间查询a[x]的前缀xor:((x+1)*getd(x))^gete(x)

改到二维上,就是树套树,直接套上去就行了。。。没仔细想为什么可以

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 typedef long long LL;
 5 int n;
 6 #define lowbit(x) ((x)&(-x))
 7 struct Y
 8 {
 9     LL d[1010],e[1010];
10     void _add(int p,LL x,LL d[])
11     {
12         for(;p<=n;p+=lowbit(p))    d[p]^=x;
13     }
14     LL _sum(int p,LL d[])
15     {
16         LL ans=0;
17         for(;p>0;p-=lowbit(p))    ans^=d[p];
18         return ans;
19     }
20     void add(int l,int r,LL x)
21     {
22         _add(l,x,d);_add(r+1,x,d);
23         _add(l,(l&1)*x,e);_add(r+1,((r+1)&1)*x,e);
24     }
25     LL sum(int l)
26     {
27         return (((l+1)&1)*_sum(l,d))^_sum(l,e);
28     }
29 }y;
30 struct X
31 {
32     Y d[1010],e[1010];
33     void _add(int p,int y1,int y2,LL x,Y d[])
34     {
35         for(;p<=n;p+=lowbit(p))    d[p].add(y1,y2,x);
36     }
37     LL _sum(int p,int y1,int y2,Y d[])
38     {
39         LL ans=0;
40         for(;p>0;p-=lowbit(p))    ans^=(d[p].sum(y2)^d[p].sum(y1-1));
41         return ans;
42     }
43     void add(int l,int r,int y1,int y2,LL x)
44     {
45         _add(l,y1,y2,x,d);_add(r+1,y1,y2,x,d);
46         _add(l,y1,y2,(l&1)*x,e);_add(r+1,y1,y2,((r+1)&1)*x,e);
47     }
48     LL sum(int l,int y1,int y2)
49     {
50         return (((l+1)&1)*_sum(l,y1,y2,d))^_sum(l,y1,y2,e);
51     }
52 }x;
53 int m;
54 int main()
55 {
56     int i,a,b,c,d,idx;LL e;
57     scanf("%d%d",&n,&m);
58     for(i=1;i<=m;i++)
59     {
60         scanf("%d",&idx);
61         if(idx==1)
62         {
63             scanf("%d%d%d%d",&a,&b,&c,&d);
64             printf("%lld\n",x.sum(c,b,d)^x.sum(a-1,b,d));
65         }
66         else
67         {
68             scanf("%d%d%d%d%lld",&a,&b,&c,&d,&e);
69             x.add(a,c,b,d,e);
70         }
71     }
72     return 0;
73 }

 

Iahub and Xors Codeforces - 341D

标签:==   space   线段   数列   turn   oid   线段树   lld   code   

原文地址:https://www.cnblogs.com/hehe54321/p/9060377.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!