P6587 超超的序列 加强 题解
toolong114514 · · 题解
P6587 超超的序列 加强 题解
题目大意
传送门。
解题思路
看到本题强制在线之后,大部分同学的乱搞之心可以死了。
本题其实是让你按某种规律去做区间修改和区间求和,而这个规律显然是
考虑研究
我们可以把
随便举一组
此时,这一组
经观察可得,
由二进制数字的性质可以得出,我们实际上是把所有下标
如何高效地处理呢?
我们考虑 0-1 trie(不知道的同学可以点蓝字去看看)。
上面所述满足条件的
查询与修改均为在 0-1 trie 中的某棵子树的整体进行。
我们只需要在 0-1 trie 中引入懒标记的思想,就可以做到查询与修改的时间复杂度均为
如果此时你仍然不知道代码该如何编写,那么请先阅读有关线段树的内容。
总的时间复杂度约为
参考代码
#include<iostream>
using namespace std;
#define int long long
const int N=5e6+10;
struct node{
int sum,laz,all;
int son[3];
}trie[N];
int root,cnt;
void ins(int &pos,int num,int sb,int zyh){
if(!pos) pos=++cnt;
trie[pos].sum+=zyh;
trie[pos].all++;
if(num==31) return;
if(sb&(1ll<<(num+1))) ins(trie[pos].son[1],num+1,sb,zyh);
else ins(trie[pos].son[0],num+1,sb,zyh);
}
void push_down(int pos){
if(trie[pos].son[0]){
trie[trie[pos].son[0]].sum+=trie[pos].laz*trie[trie[pos].son[0]].all;
trie[trie[pos].son[0]].laz+=trie[pos].laz;
}
if(trie[pos].son[1]){
trie[trie[pos].son[1]].sum+=trie[pos].laz*trie[trie[pos].son[1]].all;
trie[trie[pos].son[1]].laz+=trie[pos].laz;
}
trie[pos].laz=0;
}
void push_up(int pos){
int lson=trie[pos].son[0],rson=trie[pos].son[1];
trie[pos].sum=trie[lson].sum+trie[rson].sum;
}
void upd(int pos,int num,int hope,int sb,int yy){
if(!pos) return;
if(num==hope){
trie[pos].sum+=trie[pos].all*yy;
trie[pos].laz+=yy;
return;
}
push_down(pos);
if(sb&(1ll<<(num+1))) upd(trie[pos].son[1],num+1,hope,sb,yy);
else upd(trie[pos].son[0],num+1,hope,sb,yy);
push_up(pos);
}
int ask(int pos,int num,int hope,int sb){
if(!pos) return 0;
if(num==hope) return trie[pos].sum;
push_down(pos);
if(sb&(1ll<<(num+1))) return ask(trie[pos].son[1],num+1,hope,sb);
else return ask(trie[pos].son[0],num+1,hope,sb);
}
int a,n,m,lastans;
signed main(){
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a;
ins(root,-1,i,a);
}
while(m--){
int op,x,y,v;
cin>>op>>x>>y;
op=(op+lastans)%2+1;
if(op==1){
cin>>v;
upd(root,-1,x-1,y%(1ll<<x),v);
}else{
lastans=ask(root,-1,x-1,y%(1ll<<x));
cout<<lastans<<'\n';
}
}
return 0;
}
本代码可以通过评测。
Written by toolong114514 on 2024/4/5.