CF 85D 五颗线段树
突然发现这题和省赛的线段树类型一模一样的啊,可恨早没有做
In one well-known algorithm of finding the k-th order statistics we should divide all elements into groups of five consecutive elements and find the median of each five. A median is called the middle element of a sorted array (it's the third largest element for a group of five). To increase the algorithm's performance speed on a modern video card, you should be able to find a sum of medians in each five of the array.
A sum of medians of a sorted k-element set S = {a1, a2, ..., ak}, where a1 < a2 < a3 < ... < ak, will be understood by as
The operator stands for taking the remainder, that is stands for the remainder of dividing x by y.
To organize exercise testing quickly calculating the sum of medians for a changing set was needed.
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef __int64 lld; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int maxn = 100010; int sum[maxn<<2]; lld ans[maxn<<2][5]; int key[maxn]; int x[maxn]; int flag; char op[maxn][10]; void pushup(int rt){ for(int i=0;i<5;i++){ ans[rt][i]=ans[rt<<1][i]+ans[rt<<1|1][(i-sum[rt<<1]%5+5)%5]; } } void update(int pos,int l,int r,int rt){ sum[rt]+=2*flag-1; if(l==r){ ans[rt][0]=flag*key[pos]; return; } int m=(l+r)>>1; if(pos<=m) update(pos,lson); else update(pos,rson); pushup(rt); } int main(){ int n,i,j,tot=0; scanf("%d",&n); for(i=0;i<n;i++){ scanf("%s",op[i]); if(op[i][0]=='a' || op[i][0]=='d') scanf("%d",&x[i]),key[tot++]=x[i]; } sort(key,key+tot); tot=unique(key,key+tot)-key; for(i=0;i<n;i++){ int pos=lower_bound(key,key+tot,x[i])-key; if(op[i][0]=='a') flag=1,update(pos,1,tot,1); else if(op[i][0]=='d') flag=0,update(pos,1,tot,1); else printf("%I64d\n",ans[1][2]); } return 0; }