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

  • 相关阅读:
    [WPF VTK]三维图形开发基础(一)
    WP开发(一)
    [WPF VTK]三维图形开发基础(四)

    WIN8 下IE突然无法打开(管理员权限可打开)
    [WPF VTK]三维图形开发基础(三)
    堆排序、快排的坑
    双向链表之插入
    [WPF VTK]三维图形开发基础(二)
    [转载]Android界面设计学习日志(一)
  • 原文地址:https://www.cnblogs.com/IMGavin/p/5969411.html
Copyright © 2011-2022 走看看