Topcoder 2016 TCO Algorithm Round 3B Hard
来源:互联网 发布:深圳it 编辑:程序博客网 时间:2024/05/22 03:34
链接:https://community.topcoder.com/stat?c=problem_statement&pm=14379&rd=16798
题意:给一个n个点的图,求团的个数,每个点有一个长度为k<=18的石头剪刀布的字符串,两个点有边当且仅当i的字符串任意循环移位之后和j玩石头剪刀布胜负次数不变
题解:分析A、B之间有边的性质
定义w为3次单位根
将A看成一个多项式,系数这样定:R = 1, S = w, P = w ^ 2①
将B reverse,同样看成一个多项式:R = 1, S = w ^ w, P = w②
求一遍循环卷积,每个位置的系数写成a * w ^ 2 + b * w + c * 1的形式,我们发现a, b, c表示胜\负\平的次数,有边当且仅当最后多项式每个位置都相等
这个不太方便,我们再分析一下,求了两个多项式的点积之后得到的多项式f(x)进行idft之后所有数都相等,注意到idft实际上也算一个代值的过程,即我们带了m个值进去算出来都相等——这证明f(x)是一个常数,即x ^ i(i > 0)系数为0
还有一个性质是,B其实可以直接不变,系数用①
假设B = f(x) = ∑a[i] * x ^ i
那么rev(B) = ∑ a[m - 1 - i] * x ^ i, rev(B)系数用②实际上是
∑1 / a[m - 1 - i] * x ^ i = ∑ 1 / (a[m - 1 - i] * x ^ -i) = ∑x ^ (m - 1) / (a[m - 1 - i] * x ^ (m - 1 - i)) = x ^ (m - 1) / f(x)
即dft(rev conj B) = conj dft(B),a[i] * b[i] 和 a[i] * conj(b[i]) 是否为0是一样的
最后就一个简单的状压统计答案即可
#include <bits/stdc++.h>#define xx first#define yy second#define mp make_pair#define pb push_back#define fill(x, y) memset(x, y, sizeof x)#define copy(x, y) memcpy(x, y, sizeof x)using namespace std;typedef long long LL;typedef pair < int, int > pa;typedef complex < double > E;const int MAXN = 100005;const int MAXM = (1 << 18) + 5;const int mod = 1e9 + 7;const double pi = acos(-1);const double eps = 1e-9;int m, f[MAXM], g[MAXM], a = 22222223, b = 12345678, ans = -1;string s[MAXN];E w[20];class RPSRobots{public:int countGoodSet(int n, vector < string > r, int seed, int pR, int pP, int pS){m = r[0].length();for (int i = 0; i < r.size(); i ++) s[i] = r[i];for (int i = r.size(); i < n; i ++)for (int j = 0; j < m; j ++, seed = (1LL * seed * a + b) % mod)if (seed % (pR + pP + pS) < pR) s[i] += "R";else if(seed % (pR + pP + pS) < pR + pP) s[i] += "P";else s[i] += "S";for (int i = 0; i < n; i ++){int cur = 0;for (int j = 0; j < m; j ++)if (s[i][j] == 'R') w[j] = E(1, 0);else if (s[i][j] == 'S') w[j] = E(cos(2 * pi / 3), sin(2 * pi / 3));else w[j] = E(cos(4 * pi / 3), sin(4 * pi / 3));for (int j = 1; j < m; j ++){E ret = 0, wn = E(cos(2 * j * pi / m), sin(2 * j * pi / m));for (int k = 0; k < m; k ++) ret = (ret * wn) + w[k];if (norm(ret) > eps) cur |= 1 << j - 1;}f[cur] ++;}g[0] = 1; for (int i = 0; i < f[0]; i ++) (g[0] <<= 1) %= mod;for (int i = 1; i < 1 << m - 1; i ++) if (f[i])for (int s = (1 << m - 1) - 1 ^ i, j = s; ; j = j - 1 & s){g[i | j] = (1LL * f[i] * g[j] + g[i | j]) % mod;if (!j) break;}for (int i = 0; i < 1 << m - 1; i ++) ans = (ans + g[i]) % mod;return ans;}};
- Topcoder 2016 TCO Algorithm Round 3B Hard
- Topcoder 2017 TCO Algorithm Round 3A Hard
- Topcoder 2017 TCO Algorithm Round 3A Hard
- Topcoder 2016 TCO Algorithm Algo Semifinal 2 Hard
- Topcoder 2016 TCO Algorithm Algo Semifinal 1 Hard
- 2016 TCO Algorithm 1B SettingShield
- 2013 TCO Algorithm Round 2B - Division I, Level Two ScotlandYard
- 2012 TCO Algorithm - Round 1A
- TCO round 3A
- 2012 TCO Algorithm Round 3A - Division I, Level Two FoxAndCake
- Topcoder Open 2014 Algorithm Round 1A
- 推理题 2014 TCO Round 2B 500 SumAndProductPuzzle
- 2010 TCO Algorithm Online Round 5 - Division I, Level Two LongJourney
- Topcoder SRM 716 Hard
- Topcoder SRM 718 Hard
- Topcoder SRM 720 Hard
- Topcoder SRM 726 Hard
- 2011TCO Qual Round A
- linux 设置ftp服务器
- Firefox v54.0 稳定版
- 单链表元素的插入
- MySql ERROR_CODE:23000
- bzoj 3168: [Heoi2013]钙铁锌硒维生素 矩阵求逆+构造最小字典序完备匹配
- Topcoder 2016 TCO Algorithm Round 3B Hard
- 实现最大堆的插入和删除!
- linux与windows编码转化
- 字符串匹配的KMP算法
- 设计模式之备忘录模式(Memento)
- 排序算法
- android面试题
- python局部变量引用问题
- 用户登录界面的设置