含【最小球覆盖】【最大流isap】模板。

题面pdf

https://codeforc.es/gym/101981/attachments/download/7891/20182019-acmicpc-asia-nanjing-regional-contest-en.pdf

G---Pyramid【数论】【规律】【递推式】

题意:

度为$n$的Pyramid是一个由$\frac{n(n+1)}{2}$个三角形组成大三角形。比如度为3的Pyramid是下面这样子。

现在由这些顶点组成等边三角形,问有多少个。

思路:

zyn先放到坐标系里打了个表,然后发现差的差是一个等差数列....

于是就可以有递推关系式了。矩阵快速幂T了

所以只能解方程,把系数解出来。

注意取模求逆元!

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const ll mod=1e9+;
  5. ll n;
  6. ll fpow(ll a,ll n)
  7. {
  8. ll res=,base=a%mod;
  9. while(n)
  10. {
  11. if(n&) res*=base, res%=mod;
  12. base*=base, base%=mod;
  13. n>>=;
  14. }
  15. return res%mod;
  16. }
  17. ll inv(ll a){return fpow(a,mod-);}
  18. int main()
  19. {
  20. int T;
  21. cin>>T;
  22. while(T--)
  23. {
  24. scanf("%I64d",&n);
  25. ll ans=;
  26. ans+=fpow(n,), ans%=mod;
  27. ans+=*fpow(n,)%mod, ans%=mod;
  28. ans+=*fpow(n,)%mod, ans%=mod;
  29. ans+=*n%mod, ans%=mod;
  30. ans*=inv(), ans%=mod;
  31. printf("%I64d\n",ans);
  32. }
  33. }

I---Magic Potion【网络流】

题意:

有$n$个英雄,$m$只怪物。每个英雄可以杀某些指定的怪物,但是他们只能杀一次。现在有$k$瓶药水,喝了一瓶药水就可以多杀一只怪物,但是每个英雄最多只能喝一瓶。问他们最多可以杀多少怪物。

思路:

想dp想了半天想不出来。丢给zyn他直接就说是网络流。噢好有道理。

每个英雄和怪物之间有一条权值为1的边,源点和英雄有一个权值为1的边,怪物和汇点有权值唯一的边。

这样跑出来的最大流是不考虑喝药水的情况的答案。

现在可以喝药水了,相当于多了一个节点,源点到这个节点的边权值是k,然后这个节点和每个英雄有权值是1的边。

相当于给$k$个英雄多了一条1的流量,又限制了每个英雄只能喝一瓶。

听说Dinic T了,所以后来自己直接套的isap的板子。【其实还并不很熟网络流】

  1. #include<iostream>
  2. //#include<bits/stdc++.h>
  3. #include<cstdio>
  4. #include<cmath>
  5. #include<cstdlib>
  6. #include<cstring>
  7. #include<algorithm>
  8. #include<queue>
  9. #include<vector>
  10. #include<set>
  11. #include<climits>
  12. #include<map>
  13. using namespace std;
  14. typedef long long LL;
  15. #define N 100010
  16. #define pi 3.1415926535
  17. #define inf 0x3f3f3f3f
  18.  
  19. const int maxn = ;
  20. int n, m, k;
  21. struct edge{
  22. int v, w, nxt;
  23. }e[maxn* maxn + * maxn];
  24. int h[maxn * ], tot;
  25. int gap[maxn * ], last[maxn * ], d[maxn * ], que[maxn * ], ql, qr;
  26.  
  27. void addedge(int u, int v, int w)
  28. {
  29. e[++tot] = (edge){v, w, h[u]};
  30. h[u] = tot;
  31. e[++tot] = (edge){u, , h[v]};
  32. h[v] = tot;
  33. }
  34.  
  35. void init(int s, int t)
  36. {
  37. memset(gap, , sizeof(gap));
  38. memset(d, , sizeof(d));
  39. ++gap[d[t] = ];
  40. for(int i = ; i <= n + m + ; i++){
  41. last[i] = h[i];
  42. }
  43. que[ql = qr = ] = t;
  44. while(ql <= qr){
  45. int x = que[ql++];
  46. for(int i = h[x], v = e[i].v; i; i = e[i].nxt, v = e[i].v){
  47. if(!d[v]){
  48. ++gap[d[v] = d[x] + ], que[++qr] = v;
  49. }
  50. }
  51. }
  52. }
  53.  
  54. int aug(int x, int s, int t, int mi)
  55. {
  56. if(x == t)return mi;
  57. int flow = ;
  58. for(int &i = last[x], v = e[i].v; i; i = e[i].nxt, v = e[i].v){
  59. if(d[x] == d[v] + ){
  60. int tmp = aug(v, s, t, min(mi, e[i].w));
  61. flow += tmp, mi -= tmp, e[i].w -= tmp, e[i ^ ].w += tmp;
  62. if(!mi)return flow;
  63. }
  64. }
  65. if(!(--gap[d[x]]))d[s] = n + m + ;
  66. ++gap[++d[x]], last[x] = h[x];
  67. return flow;
  68. }
  69.  
  70. int maxflow(int s, int t)
  71. {
  72. init(s, t);
  73. int ret = aug(s, s, t, inf);
  74. while(d[s] <= n + m + )ret += aug(s, s, t, inf);
  75. return ret;
  76. }
  77.  
  78. /*void addedge(int u,int v,int w) {
  79. e[++tot]=(edge){v,w,h[u]};
  80. h[u]=tot;
  81. e[++tot]=(edge){u,0,h[v]};
  82. h[v]=tot;
  83. }
  84. void init(int s,int t) {
  85. memset(gap,0,sizeof gap),memset(d,0,sizeof d),++gap[d[t]=1];
  86. for (int i=1;i<=n + m + 3;++i) last[i]=h[i];
  87. que[ql=qr=1]=t;
  88. while (ql<=qr) {
  89. int x=que[ql++];
  90. for (int i=h[x],v=e[i].v;i;i=e[i].nxt,v=e[i].v) if (!d[v]) ++gap[d[v]=d[x]+1],que[++qr]=v;
  91. }
  92. }
  93. int aug(int x,int s,int t,int mi) {
  94. if (x==t) return mi;
  95. int flow=0;
  96. for (int &i=last[x],v=e[i].v;i;i=e[i].nxt,v=e[i].v) if (d[x]==d[v]+1) {
  97. int tmp=aug(v,s,t,min(mi,e[i].w));
  98. flow+=tmp,mi-=tmp,e[i].w-=tmp,e[i^1].w+=tmp;
  99. if (!mi) return flow;
  100. }
  101. if (!(--gap[d[x]])) d[s]=n + m + 4;
  102. ++gap[++d[x]],last[x]=h[x];
  103. return flow;
  104. }
  105. int maxflow(int s,int t) {
  106. init(s,t);
  107. int ret=aug(s,s,t,inf);
  108. while (d[s]<=n + m + 3) ret+=aug(s,s,t,inf);
  109. return ret;
  110. }*/
  111.  
  112. int main()
  113. {
  114. while(scanf("%d%d%d", &n, &m, &k) != EOF){
  115. //init(1, n+ m + 3);
  116. tot = ;
  117. memset(h, , sizeof(h));
  118. int s = , t = n + m + ;
  119. addedge(s, , k);
  120. for(int i = ; i <= n; i++){
  121. addedge(s, + i, );
  122. addedge(, + i, );
  123. int t;
  124. scanf("%d", &t);
  125. for(int j = , mon; j < t; j++){
  126. scanf("%d", &mon);
  127. addedge( + i, + n + mon, );
  128. }
  129. }
  130. for(int i = ; i <= m; i++){
  131. addedge( + n + i, t, );
  132. }
  133. printf("%d\n", maxflow(s, t));
  134. }
  135.  
  136. return ;
  137. }

D---Country Meow【最小球覆盖】

题意:

三维空间中有$n$个点,现在要在空间中找一个点,使得他到这$n$个点最远的距离最小。

思路:

就是一个最小球覆盖的板子题。找的模拟退火的板子cf过不了了。

用的三分的板子直接就过了。

  1. #include<iostream>
  2. //#include<bits/stdc++.h>
  3. #include<cstdio>
  4. #include<cmath>
  5. #include<cstdlib>
  6. #include<cstring>
  7. #include<algorithm>
  8. #include<queue>
  9. #include<vector>
  10. #include<set>
  11. #include<climits>
  12. #include<map>
  13. using namespace std;
  14. typedef long long LL;
  15. #define N 100010
  16. #define pi 3.1415926535
  17. #define inf 0x3f3f3f3f
  18.  
  19. const int maxn = ;
  20. const double eps = 1e-;
  21. typedef struct {double p[];}point;
  22. point a[maxn];
  23. int n;
  24. double cal(point now)
  25. {
  26. double ans=0.0;
  27. for(int i=;i<n;i++)
  28. ans=max(ans,sqrt((a[i].p[]-now.p[])*(a[i].p[]-now.p[])+(a[i].p[]-now.p[])*(a[i].p[]-now.p[])+(a[i].p[]-now.p[])*(a[i].p[]-now.p[])));
  29. return ans;
  30. }
  31. point del(point now,int cnt)
  32. {
  33. if(cnt>=)
  34. return now;
  35. double r=,l=-;
  36. double dr,dl;
  37. point tp1,tp2,ans1,ans2,ans;
  38. tp1=tp2=ans=now;
  39. while(r-l>eps)
  40. {
  41. dr=(*r+l)/;
  42. dl=(*l+r)/;
  43. tp1.p[cnt]=dl;
  44. tp2.p[cnt]=dr;
  45. ans1=del(tp1,cnt+);
  46. ans2=del(tp2,cnt+);
  47. if(cal(ans1)>cal(ans2))
  48. {
  49. l=dl;
  50. ans=ans1;
  51. }
  52. else
  53. {
  54. r=dr;
  55. ans=ans2;
  56. }
  57. }
  58. return ans;
  59. }
  60.  
  61. int main()
  62. { // freopen("t.txt","r",stdin);
  63. //ios::sync_with_stdio(false);
  64. //double ans;
  65. while(~scanf("%d", &n))
  66. {
  67. for(int i=; i<n; i++)
  68. //cin>>node[i].x>>node[i].y>>node[i].z;
  69. scanf("%lf%lf%lf",&a[i].p[],&a[i].p[],&a[i].p[]);
  70. //minball(n);
  71. //cout<<ans<<endl;
  72. point ans;
  73. printf("%.7f\n",cal(del(ans, )));
  74. }
  75. return ;
  76. }

K---Kangaroo Puzzle

题意:

思路:

这题代码可不能折叠啊。队友太强了!

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include <bits/stdc++.h>
  4.  
  5. using namespace std;
  6. const int MAX_N = ;
  7. char c[] = {'L', 'R', 'U', 'D'};
  8.  
  9. int main()
  10. {
  11. int N, M;
  12. cin >> N >> M;
  13. string s;
  14. for (int i = ; i <= N; i++)
  15. cin >> s;
  16. int cnt = ;
  17. srand();
  18. while (cnt++ < ) {
  19. printf("%c", c[rand()%]);
  20. }
  21. puts("");
  22. return ;
  23. }

M---Mediocre String Problem【manacher】【exKMP】

题意:

有一个串$S$,一个串$T$。现在要在$S$中选一段$S[i,j]$,和$T$中的$T[1,k]$拼起来是一串回文。问有多少种不同的三元组$(i,j,k)$

思路:

详细题解见:https://www.cnblogs.com/wyboooo/p/9982651.html

  1. #include<iostream>
  2. //#include<bits/stdc++.h>
  3. #include<cstdio>
  4. #include<cmath>
  5. //#include<cstdlib>
  6. #include<cstring>
  7. #include<algorithm>
  8. //#include<queue>
  9. #include<vector>
  10. //#include<set>
  11. //#include<climits>
  12. //#include<map>
  13. using namespace std;
  14. typedef long long LL;
  15. #define N 100010
  16. #define pi 3.1415926535
  17. #define inf 0x3f3f3f3f
  18.  
  19. const int maxn = 1e6 + ;
  20. char s[maxn], ss[maxn * ], t[maxn], s_rev[maxn];
  21. LL pre[maxn * ];
  22. int lens, lent, p[maxn * ];
  23.  
  24. int init()
  25. {
  26. ss[] = '$';
  27. ss[] = '#';
  28. int lenss = ;
  29. for(int i = ; i < lens; i++){
  30. ss[lenss++] = s[i];
  31. ss[lenss++] = '#';
  32. }
  33. ss[lenss] = '\0';
  34. return lenss;
  35. }
  36.  
  37. void manacher()
  38. {
  39. int lenss = init();
  40. int id, mx = ;
  41. for(int i = ; i < lenss; i++){
  42. if(i < mx){
  43. p[i] = min(p[ * id - i], mx - i);
  44. }
  45. else{
  46. p[i] = ;
  47. }
  48. while(ss[i - p[i]] == ss[i + p[i]])p[i]++;
  49. if(mx < i + p[i]){
  50. id = i;
  51. mx = i + p[i];
  52. }
  53. }
  54. }
  55.  
  56. int nxt[maxn],ex[maxn]; //ex数组即为extend数组
  57. //预处理计算next数组
  58. void GETNEXT(char *str)
  59. {
  60. int i=,j,po,len=strlen(str);
  61. nxt[]=len;//初始化next[0]
  62. while(str[i]==str[i+]&&i+<len)//计算next[1]
  63. i++;
  64. nxt[]=i;
  65. po=;//初始化po的位置
  66. for(i=;i<len;i++)
  67. {
  68. if(nxt[i-po]+i<nxt[po]+po)//第一种情况,可以直接得到next[i]的值
  69. nxt[i]=nxt[i-po];
  70. else//第二种情况,要继续匹配才能得到next[i]的值
  71. {
  72. j=nxt[po]+po-i;
  73. if(j<)j=;//如果i>po+nxt[po],则要从头开始匹配
  74. while(i+j<len&&str[j]==str[j+i])//计算next[i]
  75. j++;
  76. nxt[i]=j;
  77. po=i;//更新po的位置
  78. }
  79. }
  80. }
  81. //计算extend数组
  82. void EXKMP(char *s1,char *s2)
  83. {
  84. int i=,j,po,len=strlen(s1),l2=strlen(s2);
  85. GETNEXT(s2);//计算子串的next数组
  86. while(s1[i]==s2[i]&&i<l2&&i<len)//计算ex[0]
  87. i++;
  88. ex[]=i;
  89. po=;//初始化po的位置
  90. for(i=;i<len;i++)
  91. {
  92. if(nxt[i-po]+i<ex[po]+po)//第一种情况,直接可以得到ex[i]的值
  93. ex[i]=nxt[i-po];
  94. else//第二种情况,要继续匹配才能得到ex[i]的值
  95. {
  96. j=ex[po]+po-i;
  97. if(j<)j=;//如果i>ex[po]+po则要从头开始匹配
  98. while(i+j<len&&j<l2&&s1[j+i]==s2[j])//计算ex[i]
  99. j++;
  100. ex[i]=j;
  101. po=i;//更新po的位置
  102. }
  103. }
  104. }
  105.  
  106. int main()
  107. {
  108.  
  109. while(scanf("%s", s) != EOF){
  110. scanf("%s", t);
  111. lens = strlen(s);
  112. lent = strlen(t);
  113. for(int i = ; i <= lens * + ; i++){
  114. pre[i] = ;
  115. p[i] = ;
  116. ex[i] = ;
  117. }
  118. manacher();
  119. for(int i = lens * ; i >= ; i--){
  120. int x = i / ;
  121. pre[x]++;
  122. pre[x - (p[i] / )]--;
  123. }
  124. for(int i = lens; i >= ; i--){
  125. pre[i] += pre[i + ];
  126. }
  127.  
  128. for(int i = ; i <= lens; i++){
  129. s_rev[i] = s[lens - - i];
  130. }
  131. EXKMP(s_rev, t);
  132. LL ans = ;
  133. /*for(int i = 1; i <= lens; i++){
  134. cout<<pre[i]<<" "<<ex[i]<<endl;
  135. }*/
  136. for(int i = ; i <= lens; i++){
  137. //if(ex[lens - i + 1])
  138. ans += 1LL * ex[lens - i + ] * pre[i];
  139. }
  140. printf("%I64d\n", ans);
  141. }
  142. return ;
  143. }

J---Prime Game【数论】

题意:

给定$n$个数,$fra(i,j)$表示第$i$个数到第$j$个数相乘的值的不同质因子个数,求$\sum_{i=1}^{n} \sum_{j=i}^{n}fra(i,j)$

思路:

预处理把区间内的所有质数筛出来。

然后枚举每个数的质因子,找到这个质因子对答案的贡献。

每次都找到这个质因子上一次出现的位置,那么他对这段区间都是有贡献的。

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. typedef long long ll;
  5. const int MAX_N = 1e6 + ;
  6.  
  7. int prime[MAX_N+];
  8. void getPrime()
  9. {
  10. memset(prime, , sizeof prime);
  11. for (int i = ; i <= MAX_N; i++) {
  12. if (!prime[i]) prime[++prime[]] = i;
  13. for (int j = ; j <= prime[] && prime[j] <= MAX_N/i; j++) {
  14. prime[i*prime[j]] = true;
  15. if (i%prime[j] == )
  16. break;
  17. }
  18. }
  19. }
  20.  
  21. int a[MAX_N];
  22. int pre[MAX_N];
  23. int main()
  24. {
  25. getPrime();
  26. int N;
  27. cin >> N;
  28. memset(pre, , sizeof pre);
  29. for (int i = ; i <= N; i++) {
  30. scanf("%d", a+i);
  31. }
  32.  
  33. ll ans = ;
  34. for (int i = ; i <= N; i++) {
  35. for (int j = ; prime[j] <= a[i]/prime[j]; j++) {
  36. ll curp = prime[j];
  37. if (a[i] % prime[j] == ) {
  38. ll l = i - pre[curp];
  39. ll r = N-i+;
  40. ans += l*r;
  41. pre[curp] = i;
  42. while (a[i]%curp == )
  43. a[i] /= curp;
  44. }
  45. }
  46. if (a[i] > ) {
  47. ll curp = a[i];
  48. ll l = i - pre[curp];
  49. ll r = N-i+;
  50. ans += l*r;
  51. pre[curp] = i;
  52. while (a[i]%curp == )
  53. a[i] /= curp;
  54. }
  55. }
  56. cout << ans << endl;
  57. return ;
  58. }
  59. /*
  60. 10
  61. 99 62 10 47 53 9 83 33 15 24
  62. */

A---Adrien and Austin【博弈论】

题意:

有$n$个石头并有编号,每次最多可以取$k$个最少取$1$个连续的石头,两个人轮流取,谁不能取了就输了。

思路:

刚开始没看到连续的,想半天都是错的。

如果是连续的话,情况就比较简单了。

先手对于任意的一段连续的$n$都可以把他取成大小相等的两段。后手在任意一段取,先手都可以在另一段对称的取。所以先手必胜。

当$n$是奇数,$k$是$1$的时候,先手没办法取出这样的两段。所以后手能赢。$n$为$0$后手也能赢。

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. const int MAX_N = 1e6 + ;
  5. string s[] = {"Adrien", "Austin"};
  6.  
  7. int main()
  8. {
  9. int N, K;
  10. cin >> N >> K;
  11. if (N == )
  12. cout << s[] << endl;
  13. else if (K == && N% == ) {
  14. cout << s[] << endl;
  15. }
  16. else {
  17. cout << s[] << endl;
  18. }
  19. return ;
  20. }

2018ACM-ICPC南京区域赛---AJGIDKM的更多相关文章

  1. 【2013南京区域赛】部分题解 hdu4802—4812

    上周末打了一场训练赛,题目是13年南京区域赛的 这场题目有好几个本来应该是我擅长的,但是可能是太久没做比赛了各种小错误代码写的也丑各种warusn trush搞得人很不爽 全场题之一的1002也没有想 ...

  2. 2015 ACM / ICPC 亚洲区域赛总结(长春站&北京站)

    队名:Unlimited Code Works(无尽编码)  队员:Wu.Wang.Zhou 先说一下队伍:Wu是大三学长:Wang高中noip省一:我最渣,去年来大学开始学的a+b,参加今年区域赛之 ...

  3. 2014ACM/ICPC亚洲区域赛牡丹江站汇总

    球队内线我也总水平,这所学校得到了前所未有的8地方,因为只有两个少年队.因此,我们13并且可以被分配到的地方,因为13和非常大的数目.据领队谁oj在之上a谁去让更多的冠军.我和tyh,sxk,doub ...

  4. 2019 ICPC 上海区域赛总结

    2019上海区域赛现场赛总结 补题情况(以下通过率为牛客提交): 题号 标题 已通过代码 通过率 我的状态 A Mr. Panda and Dominoes 点击查看 5/29 未通过 B Prefi ...

  5. HDU 4811 Ball -2013 ICPC南京区域现场赛

    题目链接 题意:三种颜色的球,现给定三种球的数目,每次取其中一个放到桌子上,排成一条线,每次放的位置任意,问得到的最大得分. 把一个球放在末尾得到的分数是它以前球的颜色种数 把一个球放在中间得到的分数 ...

  6. 【2018 ICPC亚洲区域赛南京站 A】Adrien and Austin(博弈)

    题意: 有一排n个石子(注意n可以为0),每次可以取1~K个连续的石子,Adrien先手,Austin后手,若谁不能取则谁输. 思路: (1) n为0时的情况进行特判,后手必胜. (2) 当k=1时, ...

  7. 2014ACM/ICPC亚洲区域赛牡丹江现场赛总结

    不知道怎样说起-- 感觉还没那个比赛的感觉呢?如今就结束了. 9号.10号的时候学校还评比国奖.励志奖啥的,由于要来比赛,所以那些事情队友的国奖不能答辩.自己的励志奖班里乱搞要投票,自己又不在,真是无 ...

  8. 2016 年 ACM/ICPC 青岛区域赛 Problem C Pocky

    昨晚乱入学弟的训练赛,想了一下这个题.推导的过程中,加深了对公理化的概率论理解.$\newcommand{\d}{\mathop{}\!\mathrm{d}}$ 解法一 考虑 $ d < L$ ...

  9. 2013 ACM/ICPC 南京网络赛F题

    题意:给出一个4×4的点阵,连接相邻点可以构成一个九宫格,每个小格边长为1.从没有边的点阵开始,两人轮流向点阵中加边,如果加入的边构成了新的边长为1的小正方形,则加边的人得分.构成几个得几分,最终完成 ...

随机推荐

  1. Spark LDA实战

    选取了10个文档,其中4个来自于一篇论文,3篇来自于一篇新闻,3篇来自于另一篇新闻. 首先在pom文件中加入mysql-connector-java: <dependency> <g ...

  2. C# System.Collections.SortedList

    using System; using System.Collections; public class SamplesSortedList { public static void Main() { ...

  3. 转 c#中stringbuilder的使用

    String   对象是不可改变的.每次使用   System.String   类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间.在需要对字符串执行重复修改的情况 ...

  4. xcode 编译或者打包的时候 找不到图片的错误

    进入app路径,copy一份图片进去就好了

  5. asp.net 逻辑操作符与(&&),或(||),非(!)

    逻辑操作符与(&&),或(||),非(!)能根据参数的关系返回布尔值 public class bool{ public static void main(string [] args ...

  6. Android UI系列-----LinearLayout的综合使用

    这里将会对LinearLayout的布局方式进行一个综合的使用,通过一个例子来看看LinearLayout的嵌套布局方式,在这之前首先介绍三个属性: 1.①android:layout_weigth: ...

  7. lua -- mysql导出json

    到处的json文件放到这个目录下 E:\xg\client\cocos2d-x-2.2.2\projects\tool\propjson

  8. flink source code

    https://github.com/apache/flink/tree/master/docs https://github.com/flink-china/1.6.0 https://github ...

  9. JsonCpp 的使用

    JSON全称为JavaScript ObjectNotation,它是一种轻量级的数据交换格式,易于阅读.编写.解析.jsoncpp是c++解析JSON串常用的解析库之一. jsoncpp中主要的类: ...

  10. 小米手机安装mitmproxy证书

    [本文出自天外归云的博客园] 问题描述 小米手机在连接mitmproxy代理后通过浏览器访问mitm.it下载android证书后无法成功安装证书 设备:Redmi Note 2(红米手机) 解决方法 ...