生活随笔
收集整理的這篇文章主要介紹了
线段树位运算的三种操作(|,^,)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
銀川站網絡預選賽重賽(手動滑稽)的時候,第一道題就是這樣的一個題,雖然最后沒有判出來。不一定對,可以借鑒一下吧。
代碼如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define ll long long
using namespace std
;const int maxx
=1e5+100;
struct node
{int l
;int r
;int val
[25];int lazy1
;int lazy2
;int lazy3
;
}p
[maxx
<<2];
int n
,m
;
ll ans
;inline void pushup(int cur
)
{for(int i
=0;i
<22;i
++)p
[cur
].val
[i
]=p
[cur
<<1].val
[i
]+p
[cur
<<1|1].val
[i
];
}
inline void pushdown1(int cur
)
{int L
=p
[cur
].l
;int R
=p
[cur
].r
;if(p
[cur
].lazy1
){p
[cur
<<1].lazy1
^=p
[cur
].lazy1
;p
[cur
<<1|1].lazy1
^=p
[cur
].lazy1
;for(int i
=0;i
<22;i
++){if((p
[cur
].lazy1
>>i
)&1){p
[cur
<<1].val
[i
]=R
-L
+1-((R
-L
+1)>>1)-p
[cur
<<1].val
[i
];p
[cur
<<1|1].val
[i
]=((R
-L
+1)>>1)-p
[cur
<<1|1].val
[i
];}}p
[cur
].lazy1
=0;}
}
inline void pushdown2(int cur
)
{int L
=p
[cur
].l
;int R
=p
[cur
].r
;if(p
[cur
].lazy2
){p
[cur
<<1].lazy2
|=p
[cur
].lazy2
;p
[cur
<<1|1].lazy2
|=p
[cur
].lazy2
;for(int i
=0;i
<22;i
++){if((p
[cur
].lazy2
>>i
)&1){p
[cur
<<1].val
[i
]=R
-L
+1-((R
-L
+1)>>1);p
[cur
<<1|1].val
[i
]=((R
-L
+1)>>1);}}p
[cur
].lazy2
=0;}
}
inline void pushdown3(int cur
)
{int L
=p
[cur
].l
;int R
=p
[cur
].r
;if(p
[cur
].lazy3
){p
[cur
<<1].lazy3
&=p
[cur
].lazy3
;p
[cur
<<1|1].lazy3
&=p
[cur
].lazy3
;for(int i
=0;i
<22;i
++){if(!((p
[cur
].lazy3
>>i
)&1)) {p
[cur
<<1].val
[i
]=0;p
[cur
<<1|1].val
[i
]=0;}}p
[cur
].lazy3
=0;}
}
inline void build(int l
,int r
,int cur
)
{p
[cur
].l
=l
;p
[cur
].r
=r
;memset(p
[cur
].val
,0,sizeof(p
[cur
].val
));p
[cur
].lazy1
=0;p
[cur
].lazy2
=0;p
[cur
].lazy3
=0;if(l
==r
){int t
;scanf("%d",&t
);for (int i
= 0; i
< 22; i
++){p
[cur
].val
[i
] = (t
>> i
) & 1;}return;}int mid
=l
+r
>>1;build(l
,mid
,cur
<<1);build(mid
+1,r
,cur
<<1|1);pushup(cur
);
}
inline void update1(int l
,int r
,int v
,int cur
)
{int L
=p
[cur
].l
;int R
=p
[cur
].r
;if(l
<=L
&&R
<=r
){p
[cur
].lazy1
=p
[cur
].lazy1
^v
;for(int i
=0;i
<22;i
++){if((v
>>i
)&1) p
[cur
].val
[i
]=R
-L
+1-p
[cur
].val
[i
];}return ;}pushdown1(cur
);pushdown2(cur
);pushdown3(cur
);int mid
=L
+R
>>1;if(l
<=mid
) update1(l
,r
,v
,cur
<<1);if(r
>mid
) update1(l
,r
,v
,cur
<<1|1);pushup(cur
);
}
inline void update2(int l
,int r
,int v
,int cur
)
{int L
=p
[cur
].l
;int R
=p
[cur
].r
;if(l
<=L
&&R
<=r
){p
[cur
].lazy2
|=v
;for(int i
=0;i
<22;i
++){if((v
>>i
)&1) p
[cur
].val
[i
]=R
-L
+1;}return ;}pushdown1(cur
);pushdown2(cur
);pushdown3(cur
);int mid
=L
+R
>>1;if(l
<=mid
) update2(l
,r
,v
,cur
<<1);if(r
>mid
) update2(l
,r
,v
,cur
<<1|1);pushup(cur
);
}
inline void update3(int l
,int r
,int v
,int cur
)
{int L
=p
[cur
].l
;int R
=p
[cur
].r
;if(l
<=L
&&R
<=r
){p
[cur
].lazy3
&=v
;for(int i
=0;i
<22;i
++){if(!((v
>>i
)&1)) p
[cur
].val
[i
]=0;}return ;}pushdown1(cur
);pushdown2(cur
);pushdown3(cur
);int mid
=L
+R
>>1;if(l
<=mid
) update3(l
,r
,v
,cur
<<1);if(r
>mid
) update3(l
,r
,v
,cur
<<1|1);pushup(cur
);
}
inline void query(int l
,int r
,int cur
)
{int L
=p
[cur
].l
;int R
=p
[cur
].r
;if(l
<=L
&&R
<=r
){for(int i
=0;i
<22;i
++){ans
+=((ll
)p
[cur
].val
[i
]<<i
);}return ;}pushdown1(cur
);pushdown2(cur
);pushdown3(cur
);int mid
=L
+R
>>1;if(l
<=mid
) query(l
,r
,cur
<<1);if(r
>mid
) query(l
,r
,cur
<<1|1);pushup(cur
);
}
int main()
{int op
,l
,r
,x
;while(~scanf("%d",&n
)){build(1,n
,1);scanf("%d",&m
);while(m
--){scanf("%d",&op
);if(op
==1){ans
=0;scanf("%d%d",&l
,&r
);query(l
,r
,1);printf("%lld\n",ans
);}else if(op
==2){scanf("%d%d%d",&l
,&r
,&x
);update1(l
,r
,x
,1);}else if(op
==3){scanf("%d%d%d",&l
,&r
,&x
);update2(l
,r
,x
,1);}else if(op
==4){scanf("%d%d%d",&l
,&r
,&x
);update3(l
,r
,x
,1);}}}return 0;
}
明天就起身去銀川了,希望這一次不是無功而返。兩年努力只為最后一搏!!!加油
努力加油a啊,(o)/~
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的线段树位运算的三种操作(|,^,)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。