CSU1949: 小明的烦恼 【pb_ds】

来源:互联网 发布:石青软件官网 编辑:程序博客网 时间:2024/04/29 04:37
1949: 小明的烦恼 Submit Page     Summary    Time Limit: 4 Sec     Memory Limit: 512 Mb     Submitted: 9     Solved: 6    Description长者对小明施加了膜法,使得小明每天起床就像马丁的早晨一样。 今天小明起来后发现自己成了老板,他手下有成千上万的员工。但是有两个问题一直困扰着他,一个是如何去评价一个团队的平均薪资,似乎用平均数的方法不合适(不然会暴露出小明的工资蛤蛤 所以他采用中位数的方法,对于x个人,第x+12x+12小的工资则代表着这x个人的工资平均水平,注意这里的除以2为整除第二个问题是刚开始公司人比较少,最初每个人都是独立的,可以认为最初是n个团队,每个团队只有1人。 随着公司越来越庞大,随着合作的展开团队之间合并成更大的团队。小明想实现两种操作: 1 x,表示查询x所在的团队的工资平均水平 2 u v,表示u所在的团队,和v所在的团队合并了,保证数据合法,即不会出现两者本身就在同一团队这种情况Input多组测试数据 每组测试数据第一行两个整数n, m(1 ≤ n, m ≤ 2 × 105),表示公司的人数和查询次数 接下来一行n个数,表示每个人的工资Ai(1 ≤ Ai ≤ 109) 接下来m行表示操作,操作的意义见描述(1 ≤ x, u, v ≤ n)Output对于操作1,输出x所在的团队的工资平均水平 操作2无需输出Sample Input5 61 4 6 19 251 32 1 22 1 31 32 5 11 3Sample Output644HintSource2017年湖南多校对抗赛第12场Authorcsust

第一次接触平板电视..真是因缺思厅
pb_ds的话 就是很裸的并查集维护集合,rb_tree求第k大即可
加了启发式合并大概快了1s左右 不加也能ac

不知道为啥join函数会re

#include<stdio.h>#include <iostream>#include<stdlib.h>#include<algorithm>#include<vector>#include<deque>#include<map>#include<set>#include<queue>#include<math.h>#include<string.h>#include<string>#include<ext/pb_ds/assoc_container.hpp>#include<ext/pb_ds/tree_policy.hpp>using namespace std;using namespace __gnu_pbds;#define ll long long#define pii pair<int,int>const int N = 2e5+5;tree<pii,null_type,less<pii>,rb_tree_tag,tree_order_statistics_node_update>rbt[N];tree<pii,null_type,less<pii>,rb_tree_tag,tree_order_statistics_node_update>*tp[N];int par[N];inline int find(int x){    return par[x]=(par[x]==x?x:find(par[x]));}inline void merge(int x,int y){    x=find(x);    y=find(y);    par[x]=y;}void mergeRbt(int u,int v){    u=find(u);    v=find(v);    if(tp[v]->size()>tp[u]->size()){        swap(u,v);    }    for(auto tmp:*tp[v]){        tp[u]->insert(tmp);    }    rbt[v].clear();    merge(u,v);    tp[v]=tp[u];}int main(){    //freopen("/home/lu/Documents/r.txt","r",stdin);    //freopen("/home/lu/Documents/w.txt","w",stdout);    int n,m;    while(~scanf("%d%d",&n,&m)){        for(int i=0;i<N;++i){            tp[i]=&rbt[i];            rbt[i].clear();            par[i]=i;        }        for(int i=1;i<=n;++i){            int x;            scanf("%d",&x);            tp[i]->insert(make_pair(x,i));        }        while(m--){            int x,u,v;            scanf("%d%d",&x,&u);            if(x==2){                scanf("%d",&v);                mergeRbt(u,v);            }            else{                u=find(u);                int ans=(tp[u]->size()+1)/2;                if(ans-1>=0){                    ans=tp[u]->find_by_order(ans-1)->first;                    printf("%d\n",ans);                }            }        }    }    return 0;}
原创粉丝点击