题意:
三种操作,1.加入一个数,2,删除一个数,3,询问经过排序以后,所有下标 mod5 m o d 5 余3的数的和
思路:
注意到,当我们加入一个数以后,会让所有后面的数后移一位,删除会使得后面全部前移一位,每次移动都使得下标变化1,所以我们用线段树维护5个值,分别是当前区间下标余数为0,1,2,3,4的值的和,每次加入或删除树,我们只需要把后面的这五个数变换即可(例如我们加入一个树,后面的坐标全部加一,所以原本余数为1的值变成原本余数为0的值)
总结一下,首先读入所有操作,离散出所有数字,每次操作都将后面的数字移动一位,利用lazy节省时间,利用数值交换实现下标的移动
错误及反思:
代码:
#include<bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int N = 100100;
long long segtree[N<<2][5];
int lazy[N<<2];
int num[N<<2];
vector<int> id;
int n;
int getid(int x){return lower_bound(id.begin(),id.end(),x)-id.begin()+1;}
struct ope{
char t[10];
int x;
}op[N];
void pushup(int rt){
segtree[rt][0]=segtree[rt<<1][0]+segtree[rt<<1|1][0];
segtree[rt][1]=segtree[rt<<1][1]+segtree[rt<<1|1][1];
segtree[rt][2]=segtree[rt<<1][2]+segtree[rt<<1|1][2];
segtree[rt][3]=segtree[rt<<1][3]+segtree[rt<<1|1][3];
segtree[rt][4]=segtree[rt<<1][4]+segtree[rt<<1|1][4];
}
void pushdown(int rt){
if(lazy[rt]!=0){
lazy[rt<<1]+=lazy[rt]; lazy[rt<<1]%=5;
lazy[rt<<1|1]+=lazy[rt]; lazy[rt<<1|1]%=5;
while(lazy[rt]){
swap(segtree[rt<<1][0],segtree[rt<<1][1]); swap(segtree[rt<<1][0],segtree[rt<<1][2]);
swap(segtree[rt<<1][0],segtree[rt<<1][3]); swap(segtree[rt<<1][0],segtree[rt<<1][4]);
swap(segtree[rt<<1|1][0],segtree[rt<<1|1][1]); swap(segtree[rt<<1|1][0],segtree[rt<<1|1][2]);
swap(segtree[rt<<1|1][0],segtree[rt<<1|1][3]); swap(segtree[rt<<1|1][0],segtree[rt<<1|1][4]);
lazy[rt]--;
}
}
}
void change(int x,int v,int l,int r,int rt){
if(l==r){
num[rt]+=v;
return ;
}
int m=l+r>>1;
if(x<=m) change(x,v,lson);
else change(x,v,rson);
num[rt]=num[rt<<1]+num[rt<<1|1];
}
int getnum(int L,int R,int l,int r,int rt){
if(L<=l&&R>=r) return num[rt];
int m=l+r>>1,ans=0;
if(L<=m) ans+=getnum(L,R,lson);
if(R>m) ans+=getnum(L,R,rson);
return ans;
}
void update(int x,int op,int num,int l,int r,int rt){
if(l==r){
if(op==1)
segtree[rt][(num+1)%5]+=op*id[l-1];
else segtree[rt][(num)%5]+=op*id[l-1];
return ;
}
pushdown(rt);
int m=l+r>>1;
if(m>=x){
update(x,op,num,lson);
if(op==1){
lazy[rt<<1|1]++; lazy[rt<<1|1]%=5;
swap(segtree[rt<<1|1][0],segtree[rt<<1|1][1]); swap(segtree[rt<<1|1][0],segtree[rt<<1|1][2]);
swap(segtree[rt<<1|1][0],segtree[rt<<1|1][3]); swap(segtree[rt<<1|1][0],segtree[rt<<1|1][4]);
}
else{
lazy[rt<<1|1]+=4; lazy[rt<<1|1]%=5;
swap(segtree[rt<<1|1][0],segtree[rt<<1|1][4]); swap(segtree[rt<<1|1][0],segtree[rt<<1|1][3]);
swap(segtree[rt<<1|1][0],segtree[rt<<1|1][2]); swap(segtree[rt<<1|1][0],segtree[rt<<1|1][1]);
}
}
else update(x,op,num,rson);
pushup(rt);
return ;
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%s",op[i].t);
if(op[i].t[0]=='a'||op[i].t[0]=='d'){
scanf("%d",&op[i].x);
id.push_back(op[i].x);
}
}
sort(id.begin(),id.end()),id.erase(unique(id.begin(),id.end()),id.end());
for(int i=0;i<n;i++){
if(op[i].t[0]=='s')
printf("%lld\n",segtree[1][3]);
else if(op[i].t[0]=='a'){
int x=getid(op[i].x);
update(x,1,getnum(1,x,1,id.size(),1),1,id.size(),1);
change(x,1,1,id.size(),1);
}
else{
int x=getid(op[i].x);
update(x,-1,getnum(1,x,1,id.size(),1),1,id.size(),1);
change(x,-1,1,id.size(),1);
}
}
}