uoj792. 【UR #24】比特跳舞

神奇的题目

先考虑一个序列a[i]的情况(经典问题),维护数组f[i]表示以i为结尾的本质不同的序列个数
每次枚举上一位j,并且保证每种a只取最后一个出现的来转移
设g[a]表示最后一个a的对应的f的值,发现每次把f[i]=Σg[j],然后把g[a[i]]=f[i]=g[j]
实际就是每出现一个a,就把其他的g加到当前的g[a]上(初始g[Ø]=1)

考虑本题求ans%2,所以加可以改成异或
初始只有g[Ø]=1,其余都是0,经过大力观察发现,除了g[Ø]之外最多只有一个g=1,其余都是0
证明:当只有g[Ø]=1时,任取一个a操作都会将g[a]变1;
当有两个g=1时,操作除了g[a]以外的等价于xor 0,不变;操作g[a]会将其变成0,所以最多只有两个g=1

再观察发现,最后要求的是ans%2=1,即最后只有g[Ø]=1
那么合法的序列形如1...12...23...31...1,中间不会出现两端的数

在树上进行划分,按照1...1/2...2这样划分成若干有向链(记作短链),然后把链连起来变成路径x->y来统计
最主要的问题,是当路径xy处于lca两端并且lca处于一条短链之中,这样的怎么算

如图,把数字相同的边一分为二,将能互相到达的部分用并查集相连
那么在dfs过程中,先走完左侧的红边,回溯时把下面的贡献加到块内,在走右边的红边时查询块就可以用到了
把左边向上过红边的路径和右边另一条红边拼起来,这样得到了前一半路径;再统计下方的完整路径,二者合并得到全部短链过lca的路径

之后再求一下①顺着根-叶子的链、②xy在lca两侧但lca处没有短链(两条合法路径拼接)、③单点
就可以算出答案了


关于并查集:先用一次dfs即可构建,记录从根到当前t 的 每种颜色 的 last,每次把当前边的上半和last的下半相连即可
再观察一下发现是若干菊花图,所以只要保证是从深往浅连边即可得到菊花图,可以不用并查集
(这样写并查集也跑的很快,把连边顺序反过来就会T,因为常数↑

posted @ 2023-02-21 01:12  gmh77  阅读(99)  评论(0编辑  收藏  举报