splay去修去查求助,悬赏一关
  • 板块学术版
  • 楼主godmoo
  • 当前回复3
  • 已保存回复3
  • 发布时间2023/10/25 12:56
  • 上次更新2023/10/25 13:55:32
查看原帖
splay去修去查求助,悬赏一关
1109707
godmoo楼主2023/10/25 12:56

Description

设计一种数据结构,支持在一个序列中进行以下两种操作:

C l r k:将序列中第l到第r个数每个加上k。

Q l r:输出当前序列中第l到第r个数的总和

不能用线段树来解,不能用线段树来解,不能用线段树来解!

Input

第一行n,q(1 ≤ n,q ≤ 100000),表示序列中数的个数和操作的个数。

第二行n个数,表示初始序列(-1000000000 ≤ 每个数≤ 1000000000)

第3至2+q行,每行一个操作,意义如题目描述所示。

Output

对于每个Q操作,输出对应的结果,每个一行。

Sample Input

10 5

1 2 3 4 5 6 7 8 9 10

Q 4 4

Q 1 10

Q 2 4

C 3 6 3

Q 2 4

Sample Output

4

55

9

15

代码求调

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,q,tot,rt,data[N];
char op[10];
struct Node{int ch[2],fa,siz,id,val,sum,lzy;}tree[N];
void pushup(int u){
	tree[u].siz=tree[tree[u].ch[0]].siz+tree[tree[u].ch[1]].siz+1;
	tree[u].sum=tree[tree[u].ch[0]].sum+tree[tree[u].ch[1]].sum+tree[u].val;
}
void pushdown(int u){
	if(!tree[u].lzy) return;
	tree[tree[u].ch[0]].sum+=tree[tree[u].ch[0]].siz*tree[u].lzy;
	tree[tree[u].ch[0]].lzy+=tree[u].lzy;
	tree[tree[u].ch[0]].val+=tree[u].lzy;
	tree[tree[u].ch[1]].sum+=tree[tree[u].ch[1]].siz*tree[u].lzy;
	tree[tree[u].ch[1]].lzy+=tree[u].lzy;
	tree[tree[u].ch[1]].val+=tree[u].lzy;
	tree[u].lzy=0;
}
int create(int id,int fa){
	tree[++tot].fa=fa;
	tree[tot].val=data[id];
	tree[tot].id=id;
	return tot;
}
void build(int &u,int l,int r,int fa){
	if(l>r) return;
	int mid=l+r>>1;
	u=create(mid,fa);
	build(tree[u].ch[0],l,mid-1,u);
	build(tree[u].ch[1],mid+1,r,u);
	pushup(u);
}
bool check(int u){return u==tree[tree[u].fa].ch[1];}
void rotate(int u){
	int fa=tree[u].fa,ffa=tree[fa].fa,k=check(u),p=check(fa);
	tree[fa].ch[k]=tree[u].ch[!k],tree[tree[u].ch[!k]].fa=fa;
	tree[u].ch[!k]=fa,tree[fa].fa=u;
	tree[ffa].ch[p]=u,tree[u].fa=ffa;
	pushup(fa),pushup(u);
}
void splay(int u,int goal){
	while(tree[u].fa!=goal){
		int fa=tree[u].fa,ffa=tree[fa].fa;
		if(ffa!=goal) check(u)^check(fa)?rotate(u):rotate(fa);
		rotate(u);
	}
	if(!goal) rt=u;
}
int kth(int x){
	int u=rt;
	while(1){
		if(x<=tree[tree[u].ch[0]].siz) u=tree[u].ch[0];
		else if(x==tree[tree[u].ch[0]].siz+1)  return u;
		else x-=tree[tree[u].ch[0]].siz+1,u=tree[u].ch[1];
	}
}
int query(int l,int r){
	int x=kth(l-1),y=kth(r+1);
	splay(x,rt),splay(y,x);
	return tree[tree[y].ch[0]].sum;
}
void modify(int l,int r,int k){
	int x=kth(l-1),y=kth(r+1);
	splay(x,rt),splay(y,x);
	int u=tree[y].ch[0];
	tree[u].val+=k,tree[u].lzy+=k,tree[u].sum+=k*tree[u].siz;
	pushup(y),pushup(x);
}
//void dfs(int u){
//	if(!u) return;
//	dfs(tree[u].ch[0]);
//	printf("Node %d , id = %d , val = %d\n	lc = %d , rc = %d\n",u,tree[u].id,tree[u].val,tree[u].ch[0],tree[u].ch[1]);
//	dfs(tree[u].ch[1]);
//}
//void debug(){puts("dfs:"),printf("rt = %d\n",rt),dfs(rt);} 
int main(){
	scanf("%d%d",&n,&q);
	for(int i=2;i<=n+1;i++) scanf("%d",data+i);
	data[1]=data[n+2]=0;
	build(rt,1,n+2,0);
	for(int i=1,l,r,k;i<=q;i++){
		scanf("%s",op);
		if(op[0]=='Q') scanf("%d%d",&l,&r),l++,r++,printf("%d\n",query(l,r));		
		if(op[9]=='C') scanf("%d%d%d",&l,&r,&k),l++,r++,modify(l,r,k);
	}
	return 0;
}
/*
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
*/
2023/10/25 12:56
加载中...