AtCoderARC086 E - Smuggling Marbles

Posted ONION_CYC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoderARC086 E - Smuggling Marbles相关的知识,希望对你有一定的参考价值。

【题目】E - Smuggling Marbles

【题意】给定n+1个点的树(root=0),每个点可以选择放或不放弹珠,每一轮进行四个操作:

1.将根节点0的弹珠加入答案。

2.每个点的弹珠移向父亲。

3.如果一个点有超过2个弹珠,全部丢掉。

如果树中仍有弹珠,继续下一轮。

共有2^(n+1)种放弹珠的方案,计算所有方案的答案之和,取模1e9+7。

n<=2*10^5。

【算法】树形DP

【题解】

 

技术分享图片
#include<cstdio>
#include<cstring>
#include<cctype>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=200010,MOD=1000000007;
int read(){
    char c;int s=0,t=1;
    while(!isdigit(c=getchar()))if(c==-)t=-1;
    do{s=s*10+c-0;}while(isdigit(c=getchar()));
    return s*t;
}
struct cyc{
    int z0,z1,z2;
};
cyc operator + (cyc a,cyc b){
    cyc c;
    c.z0=1ll*a.z0*b.z0%MOD;
    c.z1=(1ll*a.z0*b.z1+1ll*a.z1*b.z0)%MOD;
    c.z2=(1ll*a.z0*b.z2+1ll*a.z2*b.z0+1ll*a.z1*b.z1+1ll*a.z2*b.z2+1ll*a.z1*b.z2+1ll*a.z2*b.z1)%MOD;
    return c;
}
vector<cyc>a[maxn];
int n,fa[maxn],first[maxn],cnt=0,tot=0,b[maxn];
struct edge{int v,from;}e[maxn*2];
void insert(int u,int v){cnt++;e[cnt].v=v;e[cnt].from=first[u];first[u]=cnt;}
int MO(int x){return x>=MOD?x-MOD:x;}
void merge(int &x,int y){
    if(a[x].size()<a[y].size())swap(x,y);
    for(int i=0;i<(int)a[y].size();i++){
        a[x][a[x].size()-i-1]=a[x][a[x].size()-i-1]+a[y][a[y].size()-i-1];
    }
}
int main(){
    n=read()+1;
    for(int i=2;i<=n;i++)fa[i]=read()+1,insert(fa[i],i);
    for(int i=n;i>=1;i--){
        int mx=0;
        if(!first[i]){
            a[b[i]=++tot].push_back((cyc){(MOD+1)/2,(MOD+1)/2,0});
        }
        else{
            b[i]=b[e[first[i]].v];
            for(int j=e[first[i]].from;j;j=e[j].from){
                mx=max(mx,min((int)a[b[i]].size(),(int)a[b[e[j].v]].size()));
                merge(b[i],b[e[j].v]);
            }
            a[b[i]].push_back((cyc){(MOD+1)/2,(MOD+1)/2,0});
        }
        for(int j=(int)a[b[i]].size()-1-1;j>=(int)a[b[i]].size()-mx-1;j--)a[b[i]][j].z0+=a[b[i]][j].z2,a[b[i]][j].z2=0;
    }
    int ans=0,N=1;
    for(int i=1;i<=n;i++)N=(N<<1)%MOD;
    for(int i=0;i<(int)a[b[1]].size();i++)ans=MO(ans+1ll*a[b[1]][i].z1*N%MOD);
    printf("%d",ans);
    return 0;
}
View Code

 

以上是关于AtCoderARC086 E - Smuggling Marbles的主要内容,如果未能解决你的问题,请参考以下文章

AtCoderARC089

AtCoderARC022

AtCoderARC090

ARC_086_E Smuggling Marbles

ARC086 E Smuggling Marbles

AtCoderARC100 题解