Digi Comp II UVALive

来源:互联网 发布:51信用卡 知乎 编辑:程序博客网 时间:2024/05/18 02:44

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4965


题意:有n个小球,m个机关,没当有一个小球按照机关的方向落下之后,机关会改变方向。给你每个机关的左右孩子以及初始的状态,问你每个机关最后的状态。

思路:看似球的数量很多,但其实不难发现每个机关的最终状态只跟机关的初始状态以及通过的球的总数有关。

所以我们想办法求出每个机关通过的总的球的个数就可以了。

也不难,模拟一下就差不多了。

从最顶上的根节点开始,一开始流过的总球数自然是n。然后依次是左右孩子。每个孩子通过的数分别应该加上(n+1)/2,n/2。

然后下一个该处理的结点应该是删除上一个点之后的入度为0的点。然后不断循环这个过程,直到所有的点都被处理完。

之后针对每个机关看一下球数的奇偶就可以了。

#include <bits/stdc++.h>using namespace std;const int MAXN=5e5+7;typedef long long ll;bool status[MAXN];ll amount[MAXN];ll n,x,y;int m,a,b,lft[MAXN],rght[MAXN],in[MAXN];char s[2];queue<int>q;void init(){    memset(status,0,sizeof(status));    memset(amount,0,sizeof(amount));    memset(in,0,sizeof(in));}int main(){    int i;    while(~scanf("%lld%d",&n,&m))    {        init();        amount[1]=n;        for(i=1; i<=m; ++i)        {            scanf("%s%d%d",s,&a,&b);            lft[i]=a;            rght[i]=b;            if(s[0]=='L')status[i]=1;            in[a]++;            in[b]++;        }        for(i=1; i<=m; ++i)if(!in[i])q.push(i);        while(!q.empty())        {            int k=q.front();            q.pop();            int l=lft[k];            int r=rght[k];            if(l||r)            {                x=(amount[k]+1)/2;                y=amount[k]-x;                if(!status[k])swap(x,y);                amount[l]+=x;                amount[r]+=y;                in[l]--;                in[r]--;                if(l&&!in[l])q.push(l);                if(r&&l!=r&&!in[r])q.push(r);            }        }        for(i=1;i<=m;++i)        {            if(amount[i]&1)status[i]^=1;            if(status[i])printf("L");            else printf("R");        }        puts("");    }    return 0;}




1 0