传送门

D - Decimal

题意:

询问\(\frac{1}{n}\)是否为有限小数。

思路:

拆质因子,看是不是只包含2和5即可,否则除不尽。

Code
  1. #include <bits/stdc++.h>
  2. #define MP make_pair
  3. #define fi first
  4. #define se second
  5. #define sz(x) (int)(x).size()
  6. using namespace std;
  7. typedef long long ll;
  8. typedef pair<int, int> pii;
  9. const int N = 1e5 + 5;
  10. int t,n;
  11. int main() {
  12. ios::sync_with_stdio(false);
  13. cin.tie(0); cout.tie(0);
  14. #ifdef Local
  15. freopen("../input.in", "r", stdin);
  16. freopen("../output.out", "w", stdout);
  17. #endif
  18. cin>>t;
  19. while(t--){
  20. cin>>n;
  21. while(n%2==0){
  22. n/=2;
  23. }
  24. while(n%5==0){
  25. n/=5;
  26. }
  27. if(n!=1)cout<<"Yes\n";
  28. else cout<<"No\n";
  29. }
  30. return 0;
  31. }

E - Escape

因为网上很多代码都有点问题,所以单独写了一下:传送门

F - Forest Program

题意:

给出一个仙人掌图(每条边最多在一个简单环中),可能不联通。

问有多少种删边方法能使得这个图变为森林。

思路:

显然对于环上的边我们至少删一条边,其它边随便删,所以关键就是找简单环。

一开始纠结点双什么的,魔改tarjan...

后面发现直接dfs找环就行,环长可以直接利用深度来求。

Code
  1. #include <bits/stdc++.h>
  2. #define MP make_pair
  3. #define fi first
  4. #define se second
  5. #define sz(x) (int)(x).size()
  6. //#define Local
  7. using namespace std;
  8. typedef long long ll;
  9. typedef pair<int, int> pii;
  10. const int N = 1e5 + 5;
  11. const int MAXN=3e5+5,MAXM=1e6+5,MOD=998244353;
  12. struct Edge{
  13. int v,next;
  14. }e[MAXM];
  15. int n,m,u,v,head[MAXN],cnt,dep[MAXN];
  16. ll ans=1,pw[500005];
  17. bool vis[MAXN],ins[MAXN];
  18. inline void addEdge(int u,int v){
  19. e[++cnt] = {v,head[u]};head[u] = cnt;
  20. }
  21. void dfs(int u,int f){
  22. ins[u]=vis[u]=1;
  23. dep[u] = dep[f] + 1;
  24. for(int i=head[u];i;i=e[i].next){
  25. int v=e[i].v;
  26. if(v==f)continue;
  27. if(ins[v]){
  28. ans = ans * (pw[dep[u]-dep[v]+1]-1+MOD)%MOD;
  29. m-=dep[u]-dep[v]+1;
  30. }
  31. if(vis[v])continue;
  32. dfs(v,u);
  33. }
  34. ins[u]=0;
  35. }
  36. int main() {
  37. ios::sync_with_stdio(false);
  38. cin.tie(0); cout.tie(0);
  39. //cout << fixed << setprecision(20);
  40. #ifdef Local
  41. freopen("../input.in", "r", stdin);
  42. freopen("../output.out", "w", stdout);
  43. #endif
  44. pw[0]=1;
  45. for(int i=1;i<=500000;i++)pw[i]=pw[i-1]*2%MOD;
  46. cin>>n>>m;
  47. for(int i=1;i<=m;i++){
  48. cin>>u>>v;
  49. addEdge(u,v);addEdge(v,u);
  50. }
  51. for(int i=1;i<=n;i++){
  52. if(!vis[i])dfs(i,0);
  53. }
  54. cout<<ans*pw[m]%MOD<<'\n';
  55. return 0;
  56. }

### I - Invoker
似乎是直接暴力dp+模拟。

Code
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define REP(i,a,b) for(register int i=(a);i<(b);i++)
  4. inline int calc();
  5. #define MAXN 3*3*3+7
  6. int dis[MAXN][MAXN];
  7. bool vis[MAXN];
  8. vector<int> pers[17];
  9. inline int skilltoid(int a, int b, int c) {
  10. int k=(1<<(2*a))+(1<<(2*b))+(1<<(2*c));
  11. #define F(x,y,z) ((1<<(2*x))+(1<<(2*y))+(1<<(2*z)))
  12. #define Q 0
  13. #define W 1
  14. #define E 2
  15. switch(k) {
  16. case F(Q, Q, Q): return 1;
  17. case F(Q, Q, W): return 2;
  18. case F(Q, Q, E): return 3;
  19. case F(W, W, W): return 4;
  20. case F(Q, W, W): return 5;
  21. case F(W, W, E): return 6;
  22. case F(E, E, E): return 7;
  23. case F(Q, E, E): return 8;
  24. case F(W, E, E): return 9;
  25. case F(Q, W, E): return 10;
  26. }
  27. return -1;
  28. #undef F
  29. #undef Q
  30. #undef W
  31. #undef E
  32. }
  33. inline int id(int a,int b,int c) {
  34. return 3*3*a+3*b+c+1;
  35. }
  36. inline void test(int z) {
  37. const char x[]="QWE";
  38. REP(a,0,3)REP(b,0,3)REP(c,0,3) if(z==id(a,b,c)) {printf("%c%c%c",x[a],x[b],x[c]);}
  39. }
  40. inline int chtoid(char x) {
  41. switch(x) {
  42. case 'Y': return 1;
  43. case 'V': return 2;
  44. case 'G': return 3;
  45. case 'C': return 4;
  46. case 'X': return 5;
  47. case 'Z': return 6;
  48. case 'T': return 7;
  49. case 'F': return 8;
  50. case 'D': return 9;
  51. case 'B': return 10;
  52. }
  53. return 0;
  54. }
  55. inline void genpers() {
  56. pers[0].push_back(0);
  57. REP(a,0,3)REP(b,0,3)REP(c,0,3) {
  58. int sid=skilltoid(a,b,c);
  59. pers[sid].push_back(id(a,b,c));
  60. }
  61. }
  62. struct node{
  63. int a,b,c;
  64. int l;
  65. };
  66. queue<node> q;
  67. inline void gendis(int a,int b,int c) {
  68. memset(vis,0,sizeof vis);
  69. int nid;
  70. int mid=id(a,b,c); dis[0][mid]=3; vis[mid]=1;
  71. q.push((node){a,b,c,0});
  72. dis[mid][mid]=0;
  73. while(!q.empty()) {
  74. node now=q.front(); q.pop();
  75. REP(d,0,3) {
  76. nid=id(now.b,now.c,d);
  77. if(!vis[nid]) {
  78. q.push((node){now.b,now.c,d,now.l+1});
  79. vis[nid]=1;
  80. dis[mid][nid]=now.l+1;
  81. }
  82. }
  83. }
  84. }
  85. char seq[100007];
  86. int dp[2][9];
  87. int main() {
  88. genpers();
  89. REP(a,0,3)REP(b,0,3)REP(c,0,3){gendis(a,b,c);}
  90. scanf("%s", seq);
  91. int len=strlen(seq);
  92. int t=0, lst=0, now=0;
  93. REP(i,0,9) dp[t][i]=0;
  94. REP(i,0,len) {
  95. lst=now; t^=1; char ch=seq[i]; now=chtoid(ch);
  96. REP(k,0,pers[now].size()) {
  97. dp[t][k]=0x3f3f3f3f;
  98. int p;
  99. REP(j,0,pers[lst].size()) {
  100. //if(dp[t^1][j]+dis[pers[lst][j]][pers[now][k]]<=dp[t][k])
  101. // test(pers[lst][j]), putchar('>'),
  102. //test(pers[now][k]), printf("%d\n", dis[pers[lst][j]][pers[now][k]]);
  103. dp[t][k]=min(dp[t][k],dp[t^1][j]+dis[pers[lst][j]][pers[now][k]]);
  104. }
  105. }
  106. //putchar('\n');
  107. }
  108. int ans=0x7fffffff;
  109. REP(i,0,pers[now].size()) {
  110. ans=min(ans,dp[t][i]);
  111. }
  112. printf("%d\n", ans+len);
  113. return 0;
  114. }

J - MUV LUV EXTRA

题意:

给出一串数字,定义\(l\)为某个循环节的长度,\(p\)为循环节出现的总长度(直到某尾才行)。

一个循环节对答案的贡献为\(a\cdot p-b\cdot l\),问最大贡献是多少。

思路:

如果我们贪心来思考的话,\(p\)肯定越大越好,\(l\)肯定越小越好。所以基本思路就是找到一个最小循环节。

因为每次循环节要直至末尾,所以我们要找\(i\cdots n,1\leq i\leq n\)的所有最小循环节。

删除一个数的贡献不容易,就考虑添加,那么倒过来直接KMP即可。

Code
  1. #include <bits/stdc++.h>
  2. #define MP make_pair
  3. #define fi first
  4. #define se second
  5. #define sz(x) (int)(x).size()
  6. #define all(x) (x).begin(), (x).end()
  7. // #define Local
  8. using namespace std;
  9. typedef long long ll;
  10. typedef pair<int, int> pii;
  11. const int N = 1e7 + 5;
  12. ll a, b;
  13. char s[N], t[N];
  14. int nxt[N];
  15. void Get_next(char *s) {
  16. int j, L = strlen(s + 1);
  17. nxt[1] = j = 0;
  18. for(int i = 2; i <= L; i++) {
  19. while(j && s[i] != s[j + 1]) j = nxt[j];
  20. if(s[i] == s[j + 1]) ++j;
  21. nxt[i] = j;
  22. }
  23. }
  24. void run() {
  25. cin >> (s + 1);
  26. int n = strlen(s + 1), m = 0;
  27. bool ok = 0;
  28. for(int i = 1; i <= n; i++) {
  29. if(s[i] == '.') {
  30. ok = 1;
  31. } else {
  32. if(ok == 0) continue;
  33. t[++m] = s[i];
  34. }
  35. }
  36. n = m;
  37. reverse(t + 1, t + n + 1);
  38. Get_next(t);
  39. ll ans = -2666666666666666666;
  40. for(int i = 1; i <= n; i++) {
  41. int l = i - nxt[i], p = i;
  42. ans = max(ans, a * p - b * l);
  43. }
  44. cout << ans << '\n';
  45. }
  46. int main() {
  47. ios::sync_with_stdio(false);
  48. cin.tie(0); cout.tie(0);
  49. cout << fixed << setprecision(20);
  50. #ifdef Local
  51. freopen("../input.in", "r", stdin);
  52. freopen("../output.out", "w", stdout);
  53. #endif
  54. while(cin >> a >> b) run();
  55. return 0;
  56. }

K - MUV LUV UNLIMITED

题意:

给出一颗以\(1\)为根的有根树,现在\(A,B\)在这颗树上玩博弈。

规则如下:每次一个人可以选择至少一个叶子结点进行删除,最后不能删除的人失败。

思路:

感觉挺有意思的一个题,定义“树枝边”为:从叶子结点往上,直到第一个分叉点的路径长度。

然后就有一个结论:

  • 若存在一个长度为\(1\)的树枝边,那么此时先手必胜。
口胡证明

若目前为一条链的情况,显然多出一条树枝边结论成立;

假设现在为多条链的情况,假设原状态为必胜态,那么多出一条边不影响;若为必败态,可以直接去掉这条树枝边把必败状态留给对方。

若多处若干树枝边,不影响结论。

所以当所有树枝边长度为\(2\)时,就时必败状态了。

现在我们已经知道树枝边小规模时的状态,那么接下来可以转换为一个石子博弈问题:给出多堆石子,每次可以选择任意堆,从上面取走一个石子,至少取一个石子,若一个人面临着存在石子数量为\(1\)的局面,就直接胜利。

这个博弈我们可以直接根据奇偶性来考虑,全为偶数时,后手有很大优势;否则,先手能将必输状态扔给对方。

代码如下:

Code
  1. #include <bits/stdc++.h>
  2. #define MP make_pair
  3. #define fi first
  4. #define se second
  5. #define sz(x) (int)(x).size()
  6. #define all(x) (x).begin(), (x).end()
  7. // #define Local
  8. using namespace std;
  9. typedef long long ll;
  10. typedef pair<int, int> pii;
  11. const int N = 1e6 + 5;
  12. int n;
  13. int d[N], a[N];
  14. std::vector<int> g[N];
  15. void dfs(int u, int fa, int &sz) {
  16. if(d[u] > 1) return;
  17. ++sz;
  18. for(auto v : g[u]) {
  19. dfs(v, u, sz);
  20. }
  21. }
  22. void run() {
  23. cin >> n;
  24. for(int i = 1; i <= n; i++) d[i] = 0, g[i].clear();
  25. for(int i = 1; i < n; i++) {
  26. int x; cin >> x;
  27. ++d[x];
  28. g[i + 1].push_back(x);
  29. }
  30. int tot = 0;
  31. for(int i = 1; i <= n; i++) {
  32. if(d[i] == 0) {
  33. int x = 0;
  34. dfs(i, 0, x);
  35. a[++tot] = x;
  36. }
  37. }
  38. for(int i = 1; i <= tot; i++) {
  39. if(a[i] & 1) {
  40. cout << "Takeru" << '\n';
  41. return;
  42. }
  43. }
  44. cout << "Meiya" << '\n';
  45. }
  46. int main() {
  47. ios::sync_with_stdio(false);
  48. cin.tie(0); cout.tie(0);
  49. cout << fixed << setprecision(20);
  50. #ifdef Local
  51. freopen("../input.in", "r", stdin);
  52. freopen("../output.out", "w", stdout);
  53. #endif
  54. int T; cin >> T;
  55. while(T--) run();
  56. return 0;
  57. }

2019 China Collegiate Programming Contest Qinhuangdao Onsite的更多相关文章

  1. 2019 China Collegiate Programming Contest Qinhuangdao Onsite F. Forest Program(DFS计算图中所有环的长度)

    题目链接:https://codeforces.com/gym/102361/problem/F 题意 有 \(n\) 个点和 \(m\) 条边,每条边属于 \(0\) 或 \(1\) 个环,问去掉一 ...

  2. The 2019 China Collegiate Programming Contest Harbin Site F. Fixing Banners

    链接: https://codeforces.com/gym/102394/problem/F 题意: Harbin, whose name was originally a Manchu word ...

  3. The 2019 China Collegiate Programming Contest Harbin Site

    题解: https://files.cnblogs.com/files/clrs97/HarbinEditorialV2.zip Code: A. Artful Paintings /* let x= ...

  4. The 2019 China Collegiate Programming Contest Harbin Site K. Keeping Rabbits

    链接: https://codeforces.com/gym/102394/problem/K 题意: DreamGrid is the keeper of n rabbits. Initially, ...

  5. The 2019 China Collegiate Programming Contest Harbin Site J. Justifying the Conjecture

    链接: https://codeforces.com/gym/102394/problem/J 题意: The great mathematician DreamGrid proposes a con ...

  6. The 2019 China Collegiate Programming Contest Harbin Site I. Interesting Permutation

    链接: https://codeforces.com/gym/102394/problem/I 题意: DreamGrid has an interesting permutation of 1,2, ...

  7. 模拟赛小结:The 2019 China Collegiate Programming Contest Harbin Site

    比赛链接:传送门 上半场5题,下半场疯狂挂机,然后又是差一题金,万年银首也太难受了. (每次银首都会想起前队友的灵魂拷问:你们队练习的时候进金区的次数多不多啊?) Problem J. Justify ...

  8. The 2015 China Collegiate Programming Contest A. Secrete Master Plan hdu5540

    Secrete Master Plan Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Othe ...

  9. The 2015 China Collegiate Programming Contest Game Rooms

    Game Rooms Time Limit: 4000/4000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

随机推荐

  1. C# WF 第12节 Timer控件

    本节内容: 1:Timer控件的简介 2:实例1  : 不停的弹出,恶意exe 3:实例2: :流水灯 4:实例3:给流水灯加上计时器和在规定的时间进行播放音乐 1:Timer控件的简介 2:实例1 ...

  2. jwt揭秘(含源码示例和视频)

    JSON Web Tokens,是一种开发的行业标准 RFC 7519 ,用于安全的表示双方之间的声明.目前,jwt广泛应用在系统的用户认证方面,特别是现在前后端分离项目. 1. jwt认证流程 在项 ...

  3. QQ第三方登录-python_web开发_django框架

    准备工作 1. 成为QQ互联的开发者 参考链接: <http://wiki.connect.qq.com/%E6%88%90%E4%B8%BA%E5%BC%80%E5%8F%91%E8%80%8 ...

  4. python3.5.3rc1学习一

    print ("Hello Pythoh3")print('我喜欢"香蕉"')print('we\'ar go to shoping.')print(" ...

  5. 读取只包含标签的xml

    什么是XML XML是可扩展标记语言(Extensible Markup Language)的缩写,其中标记是关键部分.用户可以创建内容,然后使用限定标记标记它,从而使每个单词.短语或块成为可识别.可 ...

  6. NOIP模拟赛 拓展

    题目描述 Description \(φ\) 函数是数论中非常常用的函数.对于正整数 \(x\) ,\(φ(x)\) 表示不超过 \(x\) 的所有正整数与 \(x\) 互质的个数. 现在我们对它进行 ...

  7. Nginx Rewrite域名及资源重定向

    一.正则匹配     1.匹配规则         ^$  标识符匹配后面跟-一个字符串.匹配字符串后将停止对后续的正则表达式进行匹配,如location ^~/images/,在匹配了/images ...

  8. ORB-SLAM2初步(Tracking.cpp)

    今天主要是分析一下Tracking.cpp这个文件,它是实现跟踪过程的主要文件,这里主要针对单目,并且只是截取了部分代码片段. 一.跟踪过程分析 首先构造函数中使用初始化列表对跟踪状态mState(N ...

  9. maven打包时生成源代码

    <build> <finalName>${artifactId}</finalName> <plugins> <plugin> <ar ...

  10. DNA Sorting POJ - 1007

    DNA Sorting Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 114211   Accepted: 45704 De ...