[bzoj4419] [Shoi2013]发微博

  直接每个人建棵平衡树。。

  记录一下节点添加和删除的时候,那个人总共发了多少微博。

  手写treap没比set快多少

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cstdlib>
 5 using namespace std;
 6 const int maxn=200233;
 7 int lc[1000333],rc[1000333],rnd[1000333],num[1000333],rt[maxn],tot;
 8 int sm[maxn],ans[maxn];
 9 int i,j,k,n,m,x,y;
10  
11 inline void lturn(int &x,int r){rc[x]=lc[r],lc[r]=x,x=r;}
12 inline void rturn(int &x,int l){lc[x]=rc[l],rc[l]=x,x=l;}
13 inline void ins(int &x,int v){
14     if(!x){x=++tot,num[x]=v,rnd[x]=rand()+x;return;}
15     if(v<num[x]){
16         ins(lc[x],v);
17         if(rnd[lc[x]]<rnd[x])rturn(x,lc[x]);
18     }else{
19         ins(rc[x],v);
20         if(rnd[rc[x]]<rnd[x])lturn(x,rc[x]);
21     }
22 }
23 inline void del(int &x,int v){
24     if(num[x]==v){
25         if(!lc[x]||!rc[x])x=lc[x]|rc[x];else
26         if(rnd[lc[x]]<rnd[rc[x]])
27             rturn(x,lc[x]),del(x,v);
28         else lturn(x,rc[x]),del(x,v);
29     }else if(v<num[x])del(lc[x],v);
30     else del(rc[x],v);
31 }
32 inline void dfs(int x){
33     if(lc[x])dfs(lc[x]);
34     ans[num[x]]+=sm[i];//printf("  %d",num[x]);
35     if(rc[x])dfs(rc[x]);
36 }
37  
38 int ra;char rx;
39 inline int read(){
40     rx=getchar(),ra=0;
41     while(rx<'0'||rx>'9')rx=getchar();
42     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
43 }
44 int main(){
45     n=read(),m=read();char id;
46     for(i=1;i<=m;i++){
47         for(id=getchar();id!='+'&&id!='-'&&id!='!';id=getchar());
48         x=read();
49         if(id=='!')sm[x]++;
50         if(id=='+')y=read(),ins(rt[x],y),ins(rt[y],x),ans[x]-=sm[y],ans[y]-=sm[x];
51         if(id=='-')y=read(),del(rt[x],y),del(rt[y],x),ans[x]+=sm[y],ans[y]+=sm[x];
52     }
53     for(i=1;i<=n;i++)if(rt[i])dfs(rt[i]);//,puts("");
54     for(i=1;i<n;i++)printf("%d ",ans[i]);printf("%d
",ans[n]);
55     return 0;
56 }
View Code
原文地址:https://www.cnblogs.com/czllgzmzl/p/5301789.html