zoukankan      html  css  js  c++  java
  • AGC044C Strange Dance

    Description

    There are $3^N$ people dancing in circle. We denote with $0,1,cdots ,3^N-1$ the positions in the circle, starting from an arbitrary position and going around clockwise. Initially each position in the circle is occupied by one person.

    The people are going to dance on two kinds of songs: salsa and rumba.

    • When a salsa is played, the person in position $i$ goes to position $j$, where $j$ is the number obtained replacing all digits $1$ with $2$ and all digits $2$ with $1$ when reading $i$ in base $3$ (e.g., the person in position $46$ goes to position $65$).
    • When a rumba is played, the person in position $i$ moves to position $i+1$ (with the identification $3N=0$).

    You are given a string $T=T_1T_2 cdots T_{|T|}$ such that $T_i=S$ if the ii-th song is a salsa and $T_i=R$ if it is a rumba. After all the songs have been played, the person that initially was in position $i$ is in position $P_i$. Compute the array $P_0,P_1,dots, P_{3^N-1}$

    Solution

    维护一个Trie,每个点延伸三条边表示下一个数位上是0/1/2,表示时从低位到高位

    1/2翻转的操作可以打标记

    +1取模的操作可以交换Trie的三个子节点,并在0节点下递归进行(考虑进位)

    最后对于每个叶子的权值,到达的位置就是由根到它路径上的数组成的数

    #include<iostream>
    #include<utility>
    #include<vector>
    #include<cstdio>
    using namespace std;
    int n=1,N,base[20]={1},cnt=1,tr[2000005][3],val[2000005],tag[2000005],ans[600005];
    char str[200005];
    inline int read()
    {
        int f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
        return f*w;
    }
    void build(int now,int dep,int v)
    {
        if(dep==N+1)
        {
            val[now]=v;return;
        }
        for(int i=0;i<=2;i++) tr[now][i]=++cnt,build(cnt,dep+1,v+base[dep-1]*i);
    }
    void update(int now)
    {
        if(tag[now]) swap(tr[now][1],tr[now][2]),tag[tr[now][0]]^=1,tag[tr[now][1]]^=1,tag[tr[now][2]]^=1,tag[now]=0;
        int temp=tr[now][0];
        tr[now][0]=tr[now][2],tr[now][2]=tr[now][1],tr[now][1]=temp;
        if(tr[now][0]) update(tr[now][0]);
    }
    void dfs(int now,int ret,int dep)
    {
        if(!tr[now][0])
        {
            ans[val[now]]=ret;return;
        }
        if(tag[now]) swap(tr[now][1],tr[now][2]),tag[tr[now][0]]^=1,tag[tr[now][1]]^=1,tag[tr[now][2]]^=1,tag[now]=0;
        for(int i=0;i<=2;i++) dfs(tr[now][i],ret+base[dep]*i,dep+1);
    }
    int main()
    {
        N=read();
        for(int i=1;i<=N;i++) n*=3;
        for(int i=1;i<=N;i++) base[i]=base[i-1]*3;
        build(1,1,0);
        scanf("%s",str);
        for(int i=0;str[i];i++)
        {
            if(str[i]=='S') tag[1]^=1;
            else update(1);
        }
        dfs(1,0,0);
        for(int i=0;i<n;i++) printf("%d ",ans[i]);
        return 0;
    }
    Strange Dance
  • 相关阅读:
    纪念我用word发布的第一篇文章
    第一个SpringMVCHelloWorld
    JSTL学习笔记
    bonecp的使用
    hdu 1556 树状数组
    hdu 1561 树形DP
    MYSQL使用笔记
    Android中简单实现Spinner的数据绑定
    Android中利用Application实现多个Activity间共享数据
    技术到底重要不重要?
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14029496.html
Copyright © 2011-2022 走看看