zoukankan      html  css  js  c++  java
  • UVALive5031 Graph and Queries(Treap)

    反向操作,先求出最终状态,再反向操作。

    然后就是Treap 的合并,求第K大值。

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<cmath>
    #include<utility>
    using namespace std;
    typedef long long LL;
    struct Treap{
        int size,key,pri;
        Treap *ch[2];
        Treap(int key){
            size=1;
            pri=rand();
            this->key=key;
            ch[0]=ch[1]=NULL;
        }
        int compare(int x) const{
            if(x==key) return -1;
            return x<key? 0:1;
        }
        void Maintain(){
            size=1;
            if(ch[0]!=NULL){
                size+=ch[0]->size;
            }
            if(ch[1]!=NULL){
                size+=ch[1]->size;
            }
        }
    };
    
    void Rotate(Treap* &t,int d){
        Treap *k=t->ch[d^1];
        t->ch[d^1]=k->ch[d];
        k->ch[d]=t;
        t->Maintain();
        k->Maintain();
        t=k;
    }
    
    void Insert(Treap* &t,int x){
        if(t==NULL){
            t=new Treap(x);
        }else{
            int d=x < t->key ? 0:1;
            Insert(t->ch[d],x);
            if(t->ch[d]->pri > t->pri){
                Rotate(t,d^1);
    	}
        }
        t->Maintain();
    }
    
    void Delete(Treap* &t,int x){
        int d=t->compare(x);
        if(d==-1){
            Treap *tmp=t;
            if(t->ch[0]==NULL){
                t=t->ch[1];
                delete tmp;
                tmp=NULL;
            }else if(t->ch[1]==NULL){
                t=t->ch[0];
                delete tmp;
                tmp=NULL;
            }else{
                int k=t->ch[0]->pri > t->ch[1]->pri ? 1:0;
                Rotate(t,k);
                Delete(t->ch[k],x);
            }
        }else{
            Delete(t->ch[d],x);
        }
        if(t!=NULL){
            t->Maintain();
        }
    }
    
    int Kth(Treap *t,int k){
        if(t==NULL||k<=0||k>t->size){
            return 0;
        }
        if(t->ch[0]==NULL&&k==1){
            return t->key;
        }
        if(t->ch[0]==NULL){
            return Kth(t->ch[1],k-1);
        }
        if(t->ch[0]->size>=k){
            return Kth(t->ch[0],k);
        }
        if(t->ch[0]->size+1==k){
            return t->key;
        }
        return Kth(t->ch[1],k-1-t->ch[0]->size);
    }
    
    void DeleteTreap(Treap* &t){//删除,释放内存
        if(t==NULL) return;
        if(t->ch[0]!=NULL){
            DeleteTreap(t->ch[0]);
        }
        if(t->ch[1]!=NULL){
            DeleteTreap(t->ch[1]);
        }
        delete t;
        t=NULL;
    }
    
    int n, m;
    int g[100000][3];
    stack<int> val[40000];
    struct Ope{
    	char t;
    	int a, b;
    	void init(char t1, int a1 = 0, int b1 = 0){
    		t = t1;
    		a = a1;
    		b = b1;
    	}
    }op[1000000];
    
    int fa[40000];
    Treap* fax[40000];
    
    void mergeTreap(Treap* &a, Treap* &b){
    	if(a){
    		if(a -> ch[0]){
    			mergeTreap(a -> ch[0], b);
    		}
    		if(a -> ch[1]){
    			mergeTreap(a -> ch[1], b);
    		}
    		Insert(b, a -> key);
    		delete a;
    		a = NULL;
    	}
    }
    
    int uFind(int x){
        return (fa[x] == x) ? x : fa[x] = uFind(fa[x]);
    }
    
    void add(int u, int v){
        int fx = uFind(u);
        int fy = uFind(v);
        if(fx != fy){
            if(fax[fx] -> size < fax[fy] -> size){
                mergeTreap(fax[fx], fax[fy]);
                fa[fx] = fy;
            }else{
                mergeTreap(fax[fy], fax[fx]);
                fa[fy] = fx;
            }
    
        }
    }
    
    int main(){
        int cas = 0;
        while(~scanf("%d %d", &n, &m) && n || m){
        	for(int i = 1; i <= n; i++){
        		fa[i] = i;
        		fax[i] = NULL;
        		int tp;
        		scanf("%d", &tp);
        		tp = -tp;
        		while(!val[i].empty()){
                    val[i].pop();
        		}
        		val[i].push(tp);
        	}
        	for(int i = 0; i < m; i++){
        		int u, v;
        		scanf("%d %d", &u, &v);
        		g[i][0] = u;
        		g[i][1] = v;
        		g[i][2] = 0;
        	}
        	char str[10];
        	int tot = 0;
        	while(~scanf("%s", str) && str[0] != 'E'){
        		int a, b;
        		if(str[0] == 'D'){
        			scanf("%d", &a);
        			a--;
        			g[a][2] = 1;
        		}else if(str[0] == 'C'){
        			scanf("%d %d", &a, &b);
        			b = -b;
        			val[a].push(b);
        		}else{
        			scanf("%d %d", &a, &b);
        		}
        		op[tot++].init(str[0], a, b);
    
        	}
        	for(int i = 1; i <= n; i++){
        		Insert(fax[i], val[i].top());
        	}
        	for(int i = 0; i < m; i++){
        		if(g[i][2] == 0){
        			add(g[i][0], g[i][1]);
        		}
        	}
        	int cnt = 0;
        	LL ans = 0;
        	while(tot--){
        		if(op[tot].t == 'C'){
        			int rt = uFind(op[tot].a);
        			Delete(fax[rt], val[op[tot].a].top());
        			val[op[tot].a].pop();
    
        			Insert(fax[rt], val[op[tot].a].top());
    
        		}else if(op[tot].t == 'D'){
        			int id = op[tot].a;
        			add(g[id][0], g[id][1]);
        		}else{
        			cnt++;
        			ans += Kth(fax[ uFind(op[tot].a) ], op[tot].b);
        		}
        	}
        	printf("Case %d: %.6f
    ", ++cas, (double)-ans / cnt);
        	for(int i = 1; i <= n; i++){
        		int fx = uFind(i);
        		if(fax[fx] != NULL){
        			DeleteTreap(fax[fx]);
        		}
        	}
        }
    
        return 0;
    }
    

    已经释放了内存,但在VS中使用_CrtDumpMemoryLeaks()函数检查还是有内存泄漏问题,原因还没弄清楚

  • 相关阅读:
    POJ-1189 钉子和小球(动态规划)
    POJ-1191-棋盘分割(动态规划)
    Java实现 LeetCode 730 统计不同回文子字符串(动态规划)
    Java实现 LeetCode 730 统计不同回文子字符串(动态规划)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 728 自除数(暴力)
    Java实现 LeetCode 728 自除数(暴力)
    Java实现 LeetCode 728 自除数(暴力)
  • 原文地址:https://www.cnblogs.com/IMGavin/p/5969411.html
Copyright © 2011-2022 走看看