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
  • 相关阅读:
    angular.element函数
    mknod创建命名管道(I/O缓存)
    谈谈sipXecs及其它【转】
    Linux下判断cpu物理个数、几核
    shell 中判断文件/文件夹是否存在
    一个人可以用Open IMS Core做什么呢
    linux 下更改磁盘名
    PPTP 服务器配置
    IP多媒体子系统[转维基百科]
    针对用编译的方式安装时的卸载
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14029496.html
Copyright © 2011-2022 走看看