首页 > 代码库 > hdu 4441

hdu 4441

 

insert  p:

    在p+1的位置插入v,然后  v前面的正数的个数= -v前面的负数的个数 ,这样找到的位置就是 -v的插入位置

remove v: 因为可以记录每个v的节点标号,所以直接操作。

query v:同remove。

开始时,用优先队列来维护当前最小的v值,TLE。然后用线段树模拟了一个 (本来应该是堆的)优先队列。

  1 #include <iostream>  2 #include <cstdio>  3 #include <cstring>  4 #include <algorithm>  5 #include <queue>  6 #define KT ch[ch[root][1]][0]  7 #define LC ch[x][0]  8 #define RC ch[x][1]  9 #define N 210001 10 #define lson l,mid,rt<<1|1 11 #define rson mid+1,r,rt<<1 12 #define Root 1,n,1 13 using namespace std; 14  15 typedef long long LL; 16 struct xds{ 17     int a[N<<2]; 18     int n; 19     void init(int nn){ 20         n=nn; 21         build(Root); 22     } 23     void pushup(int rt){ 24         if(a[rt<<1|1]==-1){ 25             a[rt]=a[rt<<1]; 26         } 27         else{ 28             a[rt]=a[rt<<1|1]; 29         } 30     } 31     void build(int l,int r,int rt){ 32         if(l==r){ 33             a[rt]=l; 34             return; 35         } 36         int mid=(l+r)>>1; 37         build(lson); 38         build(rson); 39         pushup(rt); 40     } 41  42     void updata(int x,int f,int l,int r,int rt){ 43         if(l==r){ 44             if(f) a[rt]=-1; 45             else a[rt]=l; 46             return; 47         } 48         int mid=(l+r)>>1; 49         if(x<=mid)updata(x,f,lson); 50         else updata(x,f,rson); 51         pushup(rt); 52     } 53     int query(int L,int R,int l,int r,int rt){ 54         if(L<=l&&r<=R){ 55             return a[rt]; 56         } 57         int mid=(l+r)>>1; 58         int ans=query(L,R,lson); 59         if(ans!=-1)return ans; 60         return query(L,R,rson); 61     } 62     void push(int val){ 63         updata(val,0,Root); 64     } 65     int top(){ 66         return query(1,n,Root); 67     } 68     void pop(){ 69         updata(top(),1,Root); 70     } 71 }Q; 72 struct SplayTree{ 73     int root; 74     int fa[N]; 75     int ch[N][2]; 76     int sz[N]; 77     int top1; 78     int top2; 79     int ss[N]; 80     int que[N]; 81  82     void pushdown(int x){ 83  84     } 85     void pushup(int x){ 86         sz[x]=1+sz[LC]+sz[RC]; 87  88         sum[x]=val[x]+sum[LC]+sum[RC]; 89         neg[x]=(val[x]<0) + neg[LC]+neg[RC]; 90     } 91     void rotate(int x,bool f){ 92         int y=fa[x]; 93         int z=fa[y]; 94         pushdown(y); 95         pushdown(x); 96         ch[y][!f]=ch[x][f]; 97         fa[ch[x][f]]=y; 98         fa[x]=z; 99         if (z) {100             ch[z][ch[z][1]==y] = x;101         }102         ch[x][f] = y;103         fa[y]=x;104         pushup(y);105     }106     void splay(int x, int g) {107         int y = fa[x];108         pushdown(x);109         while(y!=g){110             int z= fa[y];111             bool f = (ch[y][0]==x);112             if(z != g && f == (ch[z][0]==y)){113                 rotate(y,f);114             }115             rotate(x,f);116             y=fa[x];117         }118         pushup(x);119         if(g==0) root = x;120     }121     void rotateTo(int k,int g) {122         int x=root;123         pushdown(x);124         while(sz[LC] != k){125             if(k<sz[LC]){126                 x=LC;127             }else{128                 k -= sz[LC] + 1;129                 x = RC;130             }131             pushdown(x);132         }133         splay(x,g);134     }135     void build(int l,int r,int f){136         if(l>r){137             return ;138         }139         int x = (l + r) >> 1;140         LC = (x - 1 >= l)? (x - 1 + l)>> 1 :0;141         RC = (r >= x + 1)? (x + 1 + r)>> 1 :0;142         fa[x] = f;143         build(l,x - 1,x);144         build(x + 1,r,x);145         pushup(x);146     }147     void erase(int x){148         if(x==0)149             return;150         int father= fa[x];151         int head = 0, tail=0;152         for(que[tail++] =x ; head < tail; head++){153             ss[top2++] = que[head];154             if(ch[que[head]][0]){155                 que[tail++]=ch[que[head]][0];156             }157             if(ch[que[head]][1]){158                 que[tail++] = ch[que[head]][1];159             }160         }161         ch[father][ch[father][1]==x]=0;162         pushup(father);163     }164     void treaval(int x){165         if (x) {166             pushdown(x);167             treaval(LC);168             printf("@%d",val[x]);169 170             treaval(RC);171         }172     }173     int idx(int v){174         if(v==0)return 0;175         if(v>0)return v;176         else177             return -v+N;178     }179     void newNode(int &x,int c){180         if(top2){181             x = ss[--top2];182         } else {183             x = ++top1;184         }185         LC = RC = fa[x] =0;186         sz[x] = 1;187         val[x] = c;188         sum[x] = c;189         neg[x] = (c<0);190         pos[idx(c)]=x;191     }192     void makeTree(int &x, int l, int r, int f){193         if(l > r){194             return;195         }196         int m=(l+r)>>1;197         newNode(x, num[m]);198         makeTree(LC,l,m-1,x);199         makeTree(RC,m+1,r,x);200         fa[x]=f;201         pushup(x);202     }203     void debug(){204         treaval(root);205         cout<<endl;206     }207     int dfs_max(int x){208        pushdown(x);209        if(RC)return dfs_max(RC);210        return x;211     }212     int dfs_min(int x){213         pushdown(x);214         if(LC)return dfs_min(LC);215         return x;216     }217     void dele(int x){218         splay(x,0);219 //        int pre=dfs_max(LC);220 //        int nex=dfs_min(RC);221         int pre=sz[LC]-1;222         int nex=pre+2;223         rotateTo(pre,0);224         rotateTo(nex,root);225         erase(x);226         pushup(ch[root][1]);227         pushup(root);228     }229     int find(int x,int k){230         if(neg[LC]==k&&val[x]<0){splay(x,0);return sz[LC];}231         else if(neg[LC]>k){232             return find(LC,k);233         }else{234             return find(RC,k-neg[LC]-(val[x]<0));235         }236     }237     void insert(int p,int a){238 239         rotateTo(p-1,0);240         rotateTo(p,root);241         num[1]=a;242         makeTree(KT,1,1,ch[root][1]);243         pushup(ch[root][1]);244         pushup(root);245     }246 247     void insert(int p){248         int a=Q.top();Q.pop();249         insert(p+1,a);250         rotateTo(p+1,0);251         int posnum=sz[ch[root][0]]-neg[ch[root][0]]-1;252         if(posnum==neg[root]){253             insert(sz[root]-1,-a);254         }else{255             int k=find(root,posnum);256             insert(k,-a);257         }258     }259     void remove(int v){260         int x=pos[idx(v)];261         dele(x);262         x=pos[idx(-v)];263         dele(x);264 265         Q.push(v);266     }267     LL query(int v){268         int x1 = pos[idx(v)];269         int x2 = pos[idx(-v)];270         splay(x1,0);271         splay(x2,root);272         return sum[KT];273     }274     void init(){275         top1=top2=root=0;276         newNode(root,0);277         newNode(ch[root][1],0);278         fa[ch[root][1]]=root;279         pushup(ch[root][1]);280         pushup(root);281     }282     void solve(int n){283         int a;284         char op[10];285         Q.init(n+1);286         //for(int i=1;i<=n+1;i++)Q.push(i);287         for(int i=1;i<=n;i++){288             //debug();289             scanf("%s%d",op,&a);290             if(op[0]==i){291                 insert(a);292             }else if(op[0]==r){293                 remove(a);294             }else{295                 printf("%I64d\n",query(a));296             }297         }298     }299     int num[N];300     int val[N];301     LL sum[N];302     int pos[N*2];303     int neg[N];304     xds Q;305     //priority_queue <int,vector<int>,greater<int> > Q;306 }spt;307 308 int main(){309     int n;310     int cas=1;311     while(scanf("%d",&n)!=EOF){312         printf("Case #%d:\n",cas++);313         spt.init();314         spt.solve(n);315     }316 }
View Code

 

代码长,但是过程不会很艰难。

 

hdu 4441