Codeforces 371D (Union-find)

来源:互联网 发布:c语言数组定义和输出 编辑:程序博客网 时间:2024/06/12 23:35

并查集做,满了的水池合并为为最后一个为父节点

#include <cstdio>#include <algorithm>#include <cstring>#include <cstdlib>#define maxn 200010int n;int next[maxn];int v[maxn];int lft[maxn];/*union-findsomewhere change to your need*/void GxdUnionFindInit(int* gnum,int glen){    for(int i=0;i<glen;i++) gnum[i]=i;}int GxdUnionFindSearch(int* gnum,int glen,int gkey){    int key = gkey;    while(key!=next[key]) key = next[key];    int fa = key;    //path compress    key = gkey;    while(key!=fa)    {        next[key] = fa;        key = next[key];    }    return fa;}void GxdUnionFindAdd(int* gnum,int glen,int ga,int gb){    int faa = GxdUnionFindSearch(gnum,glen,ga);    int fab = GxdUnionFindSearch(gnum,glen,gb);    if(faa==fab) return ;    //here is a change to your need    //the father is always bigger than the child here.    next[std::min(faa,fab)] = std::max(faa,fab);}int main(){    memset(lft,0,sizeof(lft[0]));    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%d",&v[i]);        lft[i] = v[i];    }    GxdUnionFindInit(next,n+1);    int m;    scanf("%d",&m);    while(m--)    {        int t;        scanf("%d",&t);        if(t==1)        {            int p,x;            scanf("%d%d",&x,&p);            int last = x;            x=next[x];            while(p>=lft[x]&&x!=n)            {                p-=lft[x];                lft[x] = 0;                GxdUnionFindAdd(next,n+1,x,x+1);                x = next[x];            }            lft[x]=std::max(lft[x]-p,0);            GxdUnionFindAdd(next,n+1,last,x);        }else        {            int k;            scanf("%d",&k);            if(lft[k]==0) printf("%d\n",v[k]);            else printf("%d\n",v[k]-lft[k]);        }    }    return 0;}