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()函数检查还是有内存泄漏问题,原因还没弄清楚

  • 相关阅读:
    Qt计算器开发(三):执行效果及项目总结
    [HNOI2019]校园旅行
    How to fix nuget Unrecognized license type MIT when pack
    How to fix nuget Unrecognized license type MIT when pack
    git 通过 SublimeMerge 处理冲突
    git 通过 SublimeMerge 处理冲突
    git 上传当前分支
    git 上传当前分支
    gif 格式
    gif 格式
  • 原文地址:https://www.cnblogs.com/IMGavin/p/5969411.html
Copyright © 2011-2022 走看看