转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
对于比赛中的hime这种裸E爷不忍直视。
虽然是非常裸的数据结构,但是实在是代码捉鸡。。。。
首先用一个set维护一下,当前序列中的数。
排好序后建立Splay,至于修改操作,便是找到原来位置上的,删除之后,再找到需要插入的位置 。
感觉这个部分,我写得很麻烦,大概就是不断遍历。sad。。。。
至于查询部分,Splay肯定是找到区间,然后旋转到某棵子树。就行了
Splay维护一个子树的答案,然后还需要维护子树的序列和。
push_up的时候,根据左右子树关系就OK了。。。。
一般这种数据结构我都会RE几次,死循环。。。2333333333333
AC时刻,不能更爽。。。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set>
#define LL long long
#define db puts("BEGIN");
#define de puts("END");
#define inf 2000000000LL
#define Key_value ch[ch[root][1]][0]
using namespace std;
const int N=100015;
set<int>s;
int n,q,a[N],b[N];
struct Splay_tree{
LL sum[N],ans[N];
int size[N],pre[N],val[N],tot;
int ch[N][2],tot1,root,s[N],tot2;
//debug部分copy from hh
void Treaval(int x) {
if(x) {
Treaval(ch[x][0]);
printf("%2d ",val[x]);
Treaval(ch[x][1]);
}
}
void debug() {Treaval(root);puts("");}
//以上Debug
inline void NewNode(int &r,int k,int father){
if(tot2) r=s[--tot2];
else r=++tot1;
ch[r][0]=ch[r][1]=0;
sum[r]=k;
ans[r]=0LL;
pre[r]=father;
size[r]=1;
val[r]=k;
}
inline void Push_Up(int x){
if(x==0) return ;
int l=ch[x][0],r=ch[x][1];
size[x]=size[l]+size[r]+1;
sum[x]=sum[l]+sum[r]+val[x];
ans[x]=(LL)ans[l]+ans[r]-(LL)sum[l]*size[r]+(LL)sum[r]*size[l]+(LL)val[x]*(size[l]-size[r])-sum[l]+sum[r];
}
inline void Bulid(int &r,int L,int R,int father){
if(L>R)
return ;
int mid=(L+R)/2;
NewNode(r,a[mid],father);
Bulid(ch[r][0],L,mid-1,r);
Bulid(ch[r][1],mid+1,R,r);
Push_Up(r);
}
inline void Init(){
tot=tot1=tot2=root=0;
NewNode(root,-inf,0);
NewNode(ch[root][1],inf,root);
Bulid(Key_value,1,n,ch[root][1]);
Push_Up(ch[root][1]);
Push_Up(root);
}
inline void Rotate(int x,int kind){
int y=pre[x];
ch[y][!kind]=ch[x][kind];
pre[ch[x][kind]]=y;
if(pre[y])
ch[pre[y]][ch[pre[y]][1]==y]=x;
pre[x]=pre[y];
ch[x][kind]=y;
pre[y]=x;
Push_Up(y);
}
inline void Splay(int r,int goal){
while(pre[r]!=goal){
if(pre[pre[r]]==goal)
Rotate(r,ch[pre[r]][0]==r);
else{
int y=pre[r];
int kind=(ch[pre[y]][0]==y);
if(ch[y][kind]==r){
Rotate(r,!kind);
Rotate(r,kind);
}
else{
Rotate(y,kind);
Rotate(r,kind);
}
}
}
Push_Up(r);
if(goal==0) root=r;
}
inline void RotateTo(int k, int goal) {
int x=root;
while(k!=size[ch[x][0]]+1){
if (k<=size[ch[x][0]]){
x=ch[x][0];
}else{
k-=(size[ch[x][0]]+1);
x=ch[x][1];
}
}
Splay(x,goal);
}
inline int Get_Kth(int r,int k){
int t=size[ch[r][0]]+1;
if(t==k) return r;
if(t>k) return Get_Kth(ch[r][0],k);
else return Get_Kth(ch[r][1],k-t);
}
inline int find(int r,int num){
if(val[r]==num) return r;
else if(val[r]<num) return find(ch[r][1],num);
else return find(ch[r][0],num);
}
inline int Insert(int pos,int k){
tot++;
RotateTo(pos,0);
RotateTo(pos+1,root);
NewNode(Key_value,k,ch[root][1]);
Push_Up(ch[root][1]);
Push_Up(root);
return Key_value;
}
inline void Delete(int r){
tot--;
Splay(r,0);
int pos=size[ch[r][0]];
RotateTo(pos,0);
RotateTo(pos+2,root);
s[tot2++]=Key_value;
Key_value=0;
Push_Up(ch[root][1]);
Push_Up(root);
}
inline void add(int r,int num,int pos){
if(num<=val[r]){
if(ch[r][0]==0)
Insert(pos,num);
else
add(ch[r][0],num,pos);
}
else{
if(ch[r][1]==0)
Insert(pos+1+size[ch[r][0]],num);
else
add(ch[r][1],num,pos+size[ch[r][0]]+1);
}
}
inline void InOrder(int r){
if(r==0)
return;
InOrder(ch[r][0]);
printf("%d ",val[r]);
InOrder(ch[r][1]);
}
inline void Print(){
RotateTo(1,0);
RotateTo(tot+2,root);
InOrder(Key_value);
printf("\n");
}
}splay;
int main(){
//freopen("input.txt","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
s.insert(a[i]);
}
s.insert(inf);s.insert(-inf);
sort(a+1,a+1+n);
splay.Init();
scanf("%d",&q);
set<int>::iterator it;
while(q--){
int k,l,r;
scanf("%d%d%d",&k,&l,&r);
if(k==1){
it=s.lower_bound(b[l]);
splay.Delete(splay.find(splay.root,*it));
s.erase(it);
b[l]+=r;
s.insert(b[l]);
splay.add(splay.root,b[l],0);
}
else{
it=s.lower_bound(l);it--;
splay.Splay(splay.find(splay.root,*it),0);
it=s.upper_bound(r);
splay.Splay(splay.find(splay.root,*it),splay.root);
printf("%I64d\n",splay.ans[splay.ch[splay.ch[splay.root][1]][0]]);
}
}
return 0;
}