Problem A. ABCD

题目大意

给出一个四边形四条边AB、CD、AD、BCAB、CD、AD、BC及两条对角线AC、BDAC、BD的长度,问这个四边形的顶点能否在一个圆上

算法思路

通过余弦定理考察∠ACB\angle ACB与∠ADB\angle ADB是否相等即可。

时间复杂度: O(1)O(1)

代码

/*** Copyright © 2016 Authors. All rights reserved.* * FileName: A.cpp* Author: Beiyu Li <sysulby@gmail.com>* Date: 2016-05-09*/
#include <bits/stdc++.h>using namespace std;#define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)typedef long long LL;
typedef pair<int, int> Pii;const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;const double eps = 1e-10;
int sgn(double x) { return x < -eps? -1: x > eps; }inline double cosf(double a, double b, double c)
{ return (a * a + b * b - c * c) / (2 * a * b); }int main()
{int T, cas = 0;scanf("%d", &T);while (T--) {int ab, cd, ad, bc, ac, bd;scanf("%d%d%d%d%d%d", &ab, &cd, &ad, &bc, &ac, &bd);printf("Case #%d: %s\n", ++cas, !sgn(cosf(ac, bc, ab)- cosf(ad, bd, ab))? "Yes": "No");}return 0;
}

Problem B. Bob’s magical number

题目大意

构造一个NN个点,每个点度数都为3的无向图

算法思路

N<4N \lt 4时无解
由于共有3N2\frac{3N}{2}条边,故NN为奇数时一定无解
NN为偶数时将所有点连成环,再将对称点连起来即可

时间复杂度: O(N)O(N)

代码

/*** Copyright © 2016 Authors. All rights reserved.* * FileName: B.cpp* Author: Beiyu Li <sysulby@gmail.com>* Date: 2016-05-09*/
#include <bits/stdc++.h>using namespace std;#define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)typedef long long LL;
typedef pair<int, int> Pii;const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;int main()
{int T, cas = 0;scanf("%d", &T);while (T--) {int n;scanf("%d", &n);if (n < 4 || (n & 1)) {printf("Case #%d: No\n", ++cas);} else {printf("Case #%d: Yes\n", ++cas);For(i,1,n) {printf("%d %d\n", i, i == n? 1: i + 1);if (i <= n / 2) printf("%d %d\n", i, i + n / 2);}}}return 0;
}

Problem C. Color

题目大意

用K种颜色对长度为N的环涂色,问考虑旋转同构下本质不同的涂色方案有多少种

算法思路

由Pólya定理可知,答案等于∑i=1Nkgcd(i,N)\sum\limits_{i=1}^{N} k^{gcd(i, N)}
对于d=gcd(i,N)d = gcd(i, N),kdk^d项共有φ(Nd)\varphi(\frac{N}{d})个
所以上式化简为∑d|Nφ(Nd)kd\sum\limits_{d|N} \varphi(\frac{N}{d})k^d

时间复杂度: O(N‾‾√)O(\sqrt N)

代码

/*** Copyright © 2016 Authors. All rights reserved.* * FileName: C.cpp* Author: Beiyu Li <sysulby@gmail.com>* Date: 2016-05-09*/
#include <bits/stdc++.h>using namespace std;#define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)typedef long long LL;
typedef pair<int, int> Pii;const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;const int mod = 1000000007;int n, k, ret;
vector<Pii> fct;int pow_mod(int a, int b)
{int ret = 1;for (; b; a = (LL)a * a % mod, b >>= 1)if (b & 1) ret = (LL)ret * a % mod;return ret;
}void decomp(int n)
{fct.clear();for (int i = 2; i * i <= n; ++i) if (n % i == 0) {fct.push_back(Pii(i, 0));while (n % i) ++fct.back().second, n /= i;}if (n > 1) fct.push_back(Pii(n, 1));
}void dfs(int i, int gcd, int phi)
{if (i == fct.size()) {ret = (ret + (LL)pow_mod(k, gcd) * phi) % mod;return;}dfs(i + 1, gcd, phi);phi *= fct[i].first - 1;rep(j,fct[i].second) {gcd /= fct[i].first;dfs(i + 1, gcd, phi);phi *= fct[i].first;}
}int main()
{int T, cas = 0;scanf("%d", &T);while (T--) {scanf("%d%d", &n, &k);decomp(n);ret = 0;dfs(0, n, 1);ret = (LL)ret * pow_mod(n, mod - 2) % mod;printf("Case #%d: %d\n", ++cas, ret);}return 0;
}

Problem D. Dilettante

题目大意

问用1×1×1×21 \times 1 \times 1 \times 2的四维块在可以旋转的情况下填充2×2×4×n2 \times 2 \times 4 \times n四维空间的方案数,答案取模10000000071000000007

算法思路

将最后一维当作时间考虑可以发现,在某一时刻,前三维构成2×2×42 \times 2 \times 4的0/10/1状态立方体
对于每次转移,要么将两个相邻的0置1,要么将状态取反后到达下一时刻
我们可以先预处理构成某个状态的方案数f[S]f[S]
对于第一种转移,S→TS \to T的转移系数为f[T−S]f[T-S]
考虑相邻时刻的转移,S→TS \to T的转移系数为f[T′−S]f[T'-S],其中T′T'表示TT置反
当然,实际情况中我们枚举SS的补集的子集tt,由SS转移到(S+t)′(S + t)'
上面的DP已经可以算出正确答案,但状态SS有2162^{16}种,而nn更是达到10910^9
考虑对于某个状态,可以通过旋转/对称进行归类
再考察初始状态能到达的状态,我们得到有效状态只有997个,但仍然无法用矩阵快速幂求解
通过某种方式可以证明(然而我并不懂),答案是关于nn前面M=921M = 921项的递推式
即an=k1×an−1+k2×an−2+...+kM×an−Ma_{n} = k_{1} \times a_{n-1} + k_{2} \times a_{n-2} + ... + k_{M} \times a_{n-M}
我们可以用上面的方法暴力算出前2M2M项结果,通过高斯消元得出递推系数
通过init()init()函数打表保留前MM项答案数组a[]a[]及递推系数数组k[]k[]
后面由于是常系数齐次线性递推关系,可以用叉姐论文《线性递推关系与矩阵乘法》中的方法求解

时间复杂度: O(M2logN)O(M^2logN)

代码

/*** Copyright © 2016 Authors. All rights reserved.* * FileName: D.cpp* Author: Beiyu Li <sysulby@gmail.com>* Date: 2016-05-09*/
#include <bits/stdc++.h>using namespace std;#define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)typedef long long LL;
typedef pair<int, int> Pii;const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;const int maxs = (1 << 16) + 5;
const int maxt = 2452 + 5;              // max normalized states
const int maxc = 997 + 5;               // max reachable states
const int maxm = 921 + 5;               // max coefficient of linear recurrence
const int mod = 1000000007;int rot[] = {4, 1, 8, 2};
int rotate(int S)
{int ret = 0;for (int p = 0; p < 16; p += 4)rep(i,4) if ((S >> p) & (1 << i)) ret |= rot[i] << p;return ret;
}int flip(int S, int f)
{int ret = 0, mask = (f & 4) << 1 | f;rep(i,16) if (S & (1 << i)) ret |= 1 << (i ^ mask);return ret;
}int norm(int S)
{int ret = S;rep(pos,16) {int T = flip(S, pos >> 1);ret = min(ret, pos & 1? rotate(T) :T);}return ret;
}void gcd(int a, int b, int &g, int &x0, int &y0)
{if (!b) g = a, x0 = 1, y0 = 0;else gcd(b, a % b, g, y0, x0), y0 -= x0 * (a / b);
}int inv(int a)
{int g, x0, y0;gcd(a, mod, g, x0, y0);return (x0 + mod) % mod;
}int gauss(int a[][maxm], int n, int ret[])
{int rank = 0;bool free[maxc];memset(free, true, sizeof(free));rep(i,n) {int r = rank;while (r < n && !a[r][i]) ++r;if (r == n) continue;if (r != rank) For(j,i,n) swap(a[r][j], a[rank][j]);for (int k = rank + 1; k < n; ++k) {int tmp = (LL)a[k][i] * inv(a[i][i]) % mod;for (int j = n; j >= i; --j) a[k][j] = (a[k][j] -(LL)tmp * a[rank][j] % mod + mod) % mod;}++rank, free[i] = false;}for (int i = rank; i < n; ++i) if (a[i][n]) return -1;for (int i = n - 1, k = rank; i >= 0; --i) if (!free[i]) {ret[i] = a[--k][n];for (int j = i + 1; j < n; ++j) ret[i] = (ret[i] -(LL)a[k][j] * ret[j] % mod + mod) % mod;ret[i] = (LL)ret[i] * inv(a[k][i]) % mod;}return rank;
}int id[maxs];
int sta[maxt], tot;
int f[maxs];
int t[maxt][maxt];
bool vis[maxt];
int que[maxc], head, tail;
int g[2][maxc];
int m = 921;
int A[maxm][maxm], r[maxm];
int a[] = {121, 155969, 127027769, 249680610}; // 744708554, 4538468, ...
int k[] = {1731, 999029836, 191946633, 890219327}; // 540076999, 678513135, ...void init()
{int ALL = (1 << 16) - 1;// find normalized statesmemset(id, -1, sizeof(id));For(T,0,ALL) if (~__builtin_popcount(T) & 1) {int S = norm(T);if (~id[S]) id[T] = id[S];else id[S] = tot, sta[tot++] = S;}// calc number of constructing state S from state 0f[0] = 1;rep(k,4) rep(j,2) rep(i,2) {int p = (k << 2) | (j << 1) | i;For(S,0,ALL) if (~id[S] && (~S & (1 << p))) {if (k < 3 && (~S & (16 << p))) f[S|17<<p] += f[S];if (j < 1 && (~S & (4 << p))) f[S|5<<p] += f[S];if (i < 1 && (~S & (2 << p))) f[S|3<<p] += f[S];}}// calc transfer coefficient of normalized statesrep(i,tot) {int S = sta[i] ^ ALL;for (int T = S;; T = (T - 1) & S) {if (~id[T]) t[i][id[(sta[i]|T)^ALL]] += f[T];if (!T) break;}}// keep states which can be reached from state 0vis[0] = true, que[tail++] = 0;while (head < tail) {int i = que[head++];rep(j,tot) if (t[i][j] && !vis[j])vis[j] = true, que[tail++] = j;}// calc coefficient matrix of gaussg[1][0] = 1;rep(i,m*2) {int o = i & 1;memset(g[o], 0, sizeof(g[o]));rep(j,tail) rep(k,tail) g[o][j] = (g[o][j] +(LL)(g[o^1][k] * t[que[k]][que[j]])) % mod;if (i <= m) {A[0][i] = g[o][0];} else {rep(j,m) A[i-m][j] = A[i-m-1][j+1];A[i-m][m] = g[o][0];}}assert(~gauss(A, m, r));FILE *fout = fopen("D.arg", "w");rep(i,m) fprintf(fout, "%s%d", i? ", ": "int a[] = {", A[0][i]);fprintf(fout, "};\n");rep(i,m) fprintf(fout, "%s%d", i? ", ": "int k[] = {", r[m-i-1]);fprintf(fout, "};\n");fclose(fout);
}void multiply(int u[], int v[])
{static int t[maxm*2];memset(t, 0, sizeof(t));rep(i,m) rep(j,m) t[i+j] = (t[i+j] + (LL)u[i] * v[j]) % mod;for (int i = 2 * m - 2; i >= m; --i) {rep(j,m) t[i-j-1] = (t[i-j-1] + (LL)k[j] * t[i]) % mod;t[i] = 0;}memcpy(u, t, sizeof(t));
}int calc(int n)
{static int u[maxm*2], v[maxm*2];memset(u, 0, sizeof(u)), u[0] = 1;for (int p = 1; n; p <<= 1, n >>= 1) {if (p < m) memset(v, 0, sizeof(v)), v[p] = 1;else multiply(v, v);if (n & 1) multiply(u, v);}int ret = 0;rep(i,m) ret = (ret + (LL)u[i] * a[i]) % mod;return ret;
}int main()
{int T, cas = 0;scanf("%d", &T);// init();while (T--) {int n;scanf("%d", &n);printf("Case #%d: %d\n", ++cas, calc(n - 1));}return 0;
}

Problem E. Expectation

题目大意

对于初始为0的2×n2 \times n矩阵,每次随机选择一个子矩阵置1,问将整个矩阵全部置为1的期望步数

算法思路

首先想到,最终的期望等于每一步失败概率的累加和
考虑用二进制表示当前矩阵的状态,其中全为1的子矩阵个数为k,0的个数为oo
如果要保证该状态不变,则每次只能选择这k个子矩阵中的某个涂色,概率p=k3n(n+1)/2p = \frac{k}{3n(n+1)/2}
由容斥原理,该状态对于失败概率的贡献为∑i=1∞pi(−1)o−1=11−p(−1)o−1\sum\limits_{i=1}^{\infty}p^i(-1)^{o-1} = \frac{1}{1-p}(-1)^{o-1},也是对最后期望的贡献
不难发现,对结果有影响的只有kk和oo,可以将状态合并起来
令f[i][u][v][k][o]f[i][u][v][k][o]表示前ii列,第一行末尾有uu个1,第二行末尾有vv个1,其中有kk个全1的子矩阵,0个数奇偶性为oo的状态有多少个
则向i+1i+1列添加0/1时有4种方案,分别转移即可
计算答案时枚举某一列存在0的状态,令后面的列全为1,重新计算kk的值及概率pp
根据oo的奇偶性对答案进行贡献即可

时间复杂度: O(n3×3n(n+1)2×8)O(n^3 \times \frac{3n(n+1)}{2} \times 8)

代码

/*** Copyright © 2016 Authors. All rights reserved.* * FileName: E.cpp* Author: Beiyu Li <sysulby@gmail.com>* Date: 2016-05-10*/
#include <bits/stdc++.h>using namespace std;#define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)typedef long long LL;
typedef pair<int, int> Pii;const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;const int maxn = 20 + 1;
const int maxk = 3 * 20 * (20 + 1) / 2 + 1;long double f[maxn][maxn][maxn][maxk][2];inline int C(int n) { return 3 * n * (n + 1) / 2; }void init()
{memset(f, 0, sizeof(f)), f[0][0][0][0][0] = 1;For(i,0,19) For(u,0,i) For(v,0,i) For(k,0,C(i)) rep(o,2) {f[i+1][0][0][k][o] += f[i][u][v][k][o];f[i+1][u+1][0][k+u+1][o^1] += f[i][u][v][k][o];f[i+1][0][v+1][k+v+1][o^1] += f[i][u][v][k][o];f[i+1][u+1][v+1][k+u+v+min(u,v)+3][o] += f[i][u][v][k][o];}
}double solve(int n)
{long double ret = 0;For(i,0,n) For(u,0,i) For(v,0,i) if (!u || !v) For(k,0,C(i)) {int c = k + u * (n - i) + v * (n - i) + C(n - i);if (c == C(n)) continue;ret += f[i][u][v][k][1] / (1 - (long double)c / C(n));ret -= f[i][u][v][k][0] / (1 - (long double)c / C(n));}return ret;
}int main()
{int T, cas = 0;scanf("%d", &T);init();while (T--) {int n;scanf("%d", &n);printf("Case #%d: %.6f\n", ++cas, solve(n));}return 0;
}

Problem F. Fee

题目大意

有NN个人,每个人有一定的存款,他们想通过转账让所有人最后的钱相等
转账时银行按比例收取手续费,问最后每个人最多能有多少钱

算法思路

二分答案,考察超过midmid的钱在交付手续费后能否填补不够midmid的钱

时间复杂度: O(NlogV)O(NlogV)

代码

/*** Copyright © 2016 Authors. All rights reserved.* * FileName: F.cpp* Author: Beiyu Li <sysulby@gmail.com>* Date: 2016-05-10*/
#include <bits/stdc++.h>using namespace std;#define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)typedef long long LL;
typedef pair<int, int> Pii;const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;const double eps = 1e-10;
int sgn(double x) { return x < -eps? -1: x > eps; }const int maxn = 100000 + 5;int n;
double k, a[maxn];bool check(double b)
{double ret = 0;rep(i,n) {if (a[i] < b) ret -= (b - a[i]);if (a[i] > b) ret += (a[i] - b) * (1 - k);}return sgn(ret) >= 0;
}int main()
{int T, cas = 0;scanf("%d", &T);while (T--) {scanf("%d%lf", &n, &k);double l = 0, r = 0;rep(i,n) scanf("%lf", &a[i]), r += a[i];r /= n;while (sgn(l - r) < 0) {double mid = (l + r) / 2;if (check(mid)) l = mid;else r = mid;}printf("Case #%d: %.6f\n", ++cas, l);}return 0;
}

Problem G. Game

题目大意

Alice和Bob玩游戏,Bob有一个可以按照设定的概率随机输出11到NN的生成器,而Alice知道设定的概率
如果Alice猜对生成的数,则Alice赢1元钱
如果Alice猜的是生成的数减1,则Bob赢1元钱
问Bob在设置最优的概率,同时Alice选择最优策略的条件下,Alice赢钱的期望为多少

算法思路

若生成器输出ii的概率为PiP_{i},则Alice猜ii时赢钱的期望为Pi−Pi+1P_{i} - P_{i+1},其中PN+1P_{N+1}为0
显然Alice会选择概率下降最大的数,而Bob则要最小化这一值
不难发现,当所有概率下降的值相同,即PiP_{i}数列构成等差数列时,这一值最小
通过方程解得,答案为2N(N+1)\frac{2}{N(N + 1)}

时间复杂度: O(1)O(1)

代码

/*** Copyright © 2016 Authors. All rights reserved.* * FileName: G.cpp* Author: Beiyu Li <sysulby@gmail.com>* Date: 2016-05-10*/
#include <bits/stdc++.h>using namespace std;#define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)typedef long long LL;
typedef pair<int, int> Pii;const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;int main()
{int T, cas = 0;scanf("%d", &T);while (T--) {int n;scanf("%d", &n);printf("Case #%d: %.6f\n", ++cas, 2.0 / n / (n + 1));}return 0;
}

Problem H. Heresy

题目大意

输入nn、mm,求

∑i=1n∑j=1mi2j2gcd(i,j)

\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}i^2j^2gcd(i,j)
取模1000000007的值

算法思路

换个方向思考,先枚举gcd(i,j)gcd(i,j)的值gg,则上式等于

∑g∑i=1ng∑j=1mgi2j2g5(gcd(i,j)==1)

\sum\limits_{g}\sum\limits_{i=1}^{\frac{n}{g}}\sum\limits_{j=1}^{\frac{m}{g}}i^2j^2g^5(gcd(i,j) == 1)
其中的gcd(i,j)==1gcd(i,j)==1可使用莫比乌斯函数做容斥,即等于

∑g∑d∑i=1ng×d∑j=1mg×di2j2g5d4μ(d)

\sum\limits_{g}\sum\limits_{d}\sum\limits_{i=1}^{\frac{n}{g \times d}}\sum\limits_{j=1}^{\frac{m}{g \times d}}i^2j^2g^5d^4\mu(d)
令 D=g×dD = g \times d可得,上式等于

∑D∑d|D∑i=1nD∑j=1mDi2j2D5dμ(d)

\sum\limits_{D}\sum\limits_{d|D}\sum\limits_{i=1}^{\frac{n}{D}}\sum\limits_{j=1}^{\frac{m}{D}}i^2j^2\frac{D^5}{d}\mu(d)
提取得

∑DD5∑d|Dμ(d)d∑i=1nDi2∑j=1mDj2

\sum\limits_{D}D^5\sum\limits_{d|D}\frac{\mu(d)}{d}\sum\limits_{i=1}^{\frac{n}{D}}i^2\sum\limits_{j=1}^{\frac{m}{D}}j^2
至此,我们可以先对每个 DD进行预处理,得到

fD=D5∑d|Dμ(d)d

f_{D} = D^5\sum\limits_{d|D}\frac{\mu(d)}{d}
对于每组询问,由于 ND\frac{N}{D}与 MD\frac{M}{D}的值只有根号级别的个数
可以通过上述值的变化枚举 DD,将fDf_{D}区间和与 ii、jj平方和的乘积加到答案中即可

时间复杂度: O(NlogN+T×(N‾‾√+M‾‾√))O(NlogN + T \times (\sqrt N + \sqrt M))

代码

/*** Copyright © 2016 Authors. All rights reserved.* * FileName: H.cpp* Author: Beiyu Li <sysulby@gmail.com>* Date: 2016-05-10*/
#include <bits/stdc++.h>using namespace std;#define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)typedef long long LL;
typedef pair<int, int> Pii;const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;const int maxn = 1000000 + 5;
const int mod = 1000000007;int pow_mod(int a, int b)
{int ret = 1;for (; b; a = (LL)a * a % mod, b >>= 1)if (b & 1) ret = (LL)ret * a % mod;return ret;
}bool isp[maxn];
int prime[maxn], sz;
int mu[maxn];
int f[maxn], pre[maxn], sum[maxn];void init()
{memset(isp, true, sizeof(isp));isp[0] = isp[1] = false, mu[1] = 1;for (int i = 2; i < maxn; ++i) {if (isp[i]) prime[sz++] = i, mu[i] = -1;for (int j = 0; j < sz && prime[j] * i < maxn; ++j) {isp[prime[j]*i] = false;if (i % prime[j] == 0) {mu[prime[j]*i] = 0;break;}mu[prime[j]*i] = mu[prime[j]] * mu[i];}}for (int d = 1; d < maxn; ++d) {int k = (mu[d] * pow_mod(d, mod - 2) + mod) % mod;for (int i = 1; d * i < maxn; ++i) f[d*i] = (f[d*i] + k) % mod;}rep(i,maxn) if (i) {f[i] = (LL)f[i] * pow_mod(i, 5) % mod;pre[i] = (pre[i-1] + f[i]) % mod;sum[i] = (sum[i-1] + (LL)i * i) % mod;}
}int main()
{int T, cas = 0;scanf("%d", &T);init();while (T--) {int n, m, ret = 0;scanf("%d%d", &n, &m);for (int d = 1, nd; d <= n && d <= m; d = nd + 1) {nd = min(n / (n / d), m / (m / d));ret = (ret + (LL)(pre[nd] - pre[d-1] + mod) *sum[n/d] % mod * sum[m/d]) % mod;}printf("Case #%d: %d\n", ++cas, ret);}return 0;
}

Problem I. International Morse Code

题目大意

输入NN个单词,输出对应摩尔斯电码的按键状态,其中
“点”按1单位时间
“线”按3单位时间
元素间空1个单位
字母间空3个单位
单词间空7个单位
按下输出’=’,空白输出’.’

算法思路

按照上面说的模拟…

时间复杂度: O(N)O(N)

代码

/*** Copyright © 2016 Authors. All rights reserved.* * FileName: I.cpp* Author: Beiyu Li <sysulby@gmail.com>* Date: 2016-05-10*/
#include <bits/stdc++.h>using namespace std;#define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)typedef long long LL;
typedef pair<int, int> Pii;const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;string code[] = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.","....", "..", ".---", ".-.-", ".-..", "--", "-.","---", ".--.", "--.-", ".-.", "...", "-","..-", "...-", ".--", "-..-", "-.--", "--..",".----", "..---", "...--", "....-", ".....","-....", "--...", "---..", "----.", "-----"
};void print(char ch)
{int v = (isalpha(ch)? tolower(ch) - 'a': 26 + (ch - '0' + 9) % 10);rep(i,code[v].length()) {if (i) putchar('.');printf("%s", code[v][i] == '.'? "=": "===");}
}int main()
{int T, cas = 0;scanf("%d", &T);while (T--) {int n;scanf("%d", &n);printf("Case #%d: ", ++cas);rep(i,n) {if (i) rep(j,7) putchar('.');char buf[32];scanf("%s", buf);for (int j = 0; buf[j]; ++j) {if (j) rep(k,3) putchar('.');print(buf[j]);}}puts("");}return 0;
}

Problem J. Just another binary tree

题目大意

问大小为NN的堆中序遍历后排第kk的节点编号

算法思路

DFS
对于某棵子树计算其左子树的大小
与当前的k比较以选择进入的分支
进入右子树时注意更新k的值

时间复杂度: O(log2N)O(log^2N)

代码

/*** Copyright © 2016 Authors. All rights reserved.* * FileName: J.cpp* Author: Beiyu Li <sysulby@gmail.com>* Date: 2016-05-10*/
#include <bits/stdc++.h>using namespace std;#define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)typedef long long LL;
typedef pair<int, int> Pii;const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;int dfs(int v, int n, int k)
{int p = 1;while (p * 2 <= n) p *= 2;int l = p / 2 - 1 + min(n - (p - 1), p / 2);if (n == 1 || k == l + 1) return v;return k <= l? dfs(v * 2, l, k): dfs(v * 2 + 1, n - l - 1, k - l - 1);
}int main()
{int T, cas = 0;scanf("%d", &T);while (T--) {int n, k;scanf("%d%d", &n, &k);printf("Case #%d: %d\n", ++cas, dfs(1, n, k));}return 0;
}

Problem K. Kay’s function

题目大意

f[0]=af[0] = a
f[1]=bf[1] = b
f[n]=f[n−1] xor f[n−2]f[n] = f[n-1]\ xor\ f[n-2]
输入aa、bb、nn,输出f[n]f[n]

算法思路

显然这个序列由a,b,a xor b,...a, b, a\ xor\ b, ...不断循环构成,故输出f[n mod 3]f[n\ mod\ 3]即可

时间复杂度: O(1)O(1)

代码

/*** Copyright © 2016 Authors. All rights reserved.* * FileName: K.cpp* Author: Beiyu Li <sysulby@gmail.com>* Date: 2016-05-10*/
#include <bits/stdc++.h>using namespace std;#define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)typedef long long LL;
typedef pair<int, int> Pii;const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;int main()
{int T, cas = 0;scanf("%d", &T);while (T--) {int n, f[3];scanf("%d%d%d", &f[0], &f[1], &n);f[2] = f[0] ^ f[1];printf("Case #%d: %d\n", ++cas, f[n%3]);}return 0;
}

致谢

感谢mayf3同学提供的数据及部分指导

GDCPC2016题解 by lby@SYSU | Asiimov相关推荐

  1. GDCPC2015题解 by lby@SYSU_Spirit_Moon

    Problem A. Article 题目大意 DRD要在一个编辑器里打出N个字符并保存 对于某一时刻,有两种操作: 保存当前的结果,需要x单位时间 打出一个字符,需要1单位时间,且有p的概率回到上个 ...

  2. 蓝桥楼赛第23期-Python-新冠疫情数据统计 题解

    题目描述 2020 年,新冠疫情肆掠全球.约翰·霍普金斯大学 跟踪了全球病例数据,包括总病例数.COVID-19 传播速度以及全球爆发情况.我们拿到了截止于某日的疫情数据,希望通过 Python 统计 ...

  3. [JS][dfs]题解 | #迷宫问题#

    题解 | #迷宫问题# 题目链接 迷宫问题 题目描述 定义一个二维数组 N*M ,如 5 × 5 数组下所示: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 1, 1 ...

  4. [JS][dp]题解 | #打家劫舍(一)#

    题解 | #打家劫舍(一)# 题目链接 打家劫舍(一) 题目描述 描述 你是一个经验丰富的小偷,准备偷沿街的一排房间,每个房间都存有一定的现金,为了防止被发现,你不能偷相邻的两家,即,如果偷了第一家, ...

  5. [JS]题解 | #魔法数字#

    题解 | #魔法数字# 题目链接 魔法数字 题目描述 牛妹给牛牛写了一个数字n,然后又给自己写了一个数字m,她希望牛牛能执行最少的操作将他的数字转化成自己的. 操作共有三种,如下: 在当前数字的基础上 ...

  6. [JS]题解 | #岛屿数量#

    题解 | #岛屿数量# 题目链接 岛屿数量 题目描述 时间限制:1秒 空间限制:256M 描述 给一个01矩阵,1代表是陆地,0代表海洋, 如果两个1相邻,那么这两个1属于同一个岛.我们只考虑上下左右 ...

  7. [JS] 题解:提取不重复的整数

    题解:提取不重复的整数 https://www.nowcoder.com/practice/253986e66d114d378ae8de2e6c4577c1 时间限制:1秒 空间限制:32M 描述 输 ...

  8. 洛谷-题解 P2672 【推销员】

    独门思路!链表加优先队列! 这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法 思路: 1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了 ...

  9. [洛谷1383]高级打字机 题解

    题解 这道题一看就珂以用主席树啊 这是一道神奇的题目,那么我们先敲一个主席树,然后维护一个数组len,表示下一次应该在len + 1插入, 之后对于T操作,在上一个版本的len + 1上直接执行插入 ...

最新文章

  1. WPF中的依赖项属性
  2. objdump反汇编用法示例
  3. Go sync.WaitGroup的用法
  4. Java中MySQL事务处理举例
  5. Ubuntu server下“初始化月份字符串出错”的解决
  6. 怎样解决MySQL数据库主从复制延迟的问题?
  7. 【java】linux命令获取百度的主页-模拟Socket三次握手
  8. 小微企业——客户借款原因分析
  9. iOS语音识别功能实现
  10. JavaScript基础---字符串方法
  11. 滚动条----SCROLLBAR
  12. Hibernate annotation配置方式的MappedBy使用详解
  13. 老男孩python课程_老男孩python课程
  14. Suricata/Snort规则参考
  15. 中级软件设计师知识点总结
  16. UVALive 3713 Astronauts(2SAT)
  17. python读取txt文件并将其转换为Dataframe格式
  18. 太阳照常升起(C大调)
  19. 机器人瓦力漫威_漫威归来的发明家
  20. 02 ABY框架的搭建及踩到的坑

热门文章

  1. 门禁系统数据库服务器如何配置,门禁系统服务器安装.doc
  2. 转:性能测试解惑之并发压力
  3. Python+Matplotlib可视化三次贝塞尔曲线的4个调和函数
  4. 【黑马程序员】SpringBoot2学习笔记
  5. 12型拖拉机离合器壳体落料、首次拉伸复合模设计(说明书 CAD图纸 开题报告 任务书 外文翻译……)
  6. VLC 音视频播放,支持添加视频列表和循环播放
  7. 单片机救护车声音 c语言,51单片机模拟救护车声音 喇叭滴答声 源程序
  8. 区块链技术:天使 OR 魔鬼?
  9. 【计算机毕业设计】五篇优秀的管理系统毕业设计(附下载源码和论文)
  10. 数学分析-第一章-极限理论