C - Align

考的时候,我大胆猜了结论,就是一小一大一小一大这么排

证明的话,由于我们总是要加上相邻的最大值而减去最小值,我们就让最大值都保持在前面

如果长度为奇数,要么就是大小大小大,要么是小大小大小

第一种要求是靠中间的位置填(n + 1) / 2个最大值中较大的,两边填较小的(两边只被加了一次)

第二种要求是靠中间的位置填(n + 1) / 2个最小值中较小的,两边填较大的(两边被减了一次)

如果长度为偶数

小大小大小大和大小大小大小显然等价

我们把最小值中较大的放在最前,最大值较小的放在最后即可

代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <vector>
  6. #define fi first
  7. #define se second
  8. #define pii pair<int,int>
  9. #define mp make_pair
  10. #define pb push_back
  11. #define space putchar(' ')
  12. #define enter putchar('\n')
  13. //#define ivorysi
  14. #define MAXN 100005
  15. using namespace std;
  16. typedef long long int64;
  17. template<class T>
  18. void read(T &res) {
  19. res = 0;char c = getchar();T f = 1;
  20. while(c < '0' || c > '9') {
  21. if(c == '-') f = -1;
  22. c = getchar();
  23. }
  24. while(c >= '0' && c <= '9') {
  25. res = res * 10 + c - '0';
  26. c = getchar();
  27. }
  28. res *= f;
  29. }
  30. template<class T>
  31. void out(T x) {
  32. if(x < 0) {x = -x;putchar('-');}
  33. if(x >= 10) out(x / 10);
  34. putchar('0' + x % 10);
  35. }
  36. int N;
  37. int A[MAXN];
  38. int main() {
  39. #ifdef ivorysi
  40. freopen("f1.in","r",stdin);
  41. #endif
  42. read(N);
  43. for(int i = 1 ; i <= N ; ++i) read(A[i]);
  44. sort(A + 1,A + N + 1);
  45. if(N & 1) {
  46. int t = N / 2 + 1;
  47. int L = 1,R = N;int64 res = 0;
  48. for(int i = 1 ; i <= t - 2; ++i) {
  49. res -= 2 * A[i];
  50. }
  51. res = res - A[t - 1] - A[t];
  52. for(int i = t + 1 ; i <= N ; ++i) res += 2 * A[i];
  53. int64 tmp = 0;
  54. t = N - (N / 2 + 1) + 1;
  55. for(int i = N ; i >= t + 2 ; --i) tmp += 2 * A[i];
  56. tmp += A[t + 1] + A[t];
  57. for(int i = 1 ; i < t ; ++i) tmp -= 2 * A[i];
  58. res = max(res,tmp);
  59. out(res);enter;
  60. }
  61. else {
  62. int L = 1,R = N;
  63. int64 res = 0;
  64. for(int i = 1 ; i <= N - 2 ; ++i) {
  65. if(i & 1) res -= 2 * A[L++];
  66. else res += 2 * A[R--];
  67. }
  68. res += A[R] - A[L];
  69. out(res);enter;
  70. }
  71. return 0;
  72. }

D - Crossing

把每个元组之间有两个相同元素当做唯一的连边方式,那么k个元组需要的边是

\(\frac{k(k - 1)}{2}\),我们先看N能不能解出这个k,然后构造方法就是暴力给没连边的元组连边就好了

代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <vector>
  6. #define fi first
  7. #define se second
  8. #define pii pair<int,int>
  9. #define mp make_pair
  10. #define pb push_back
  11. #define space putchar(' ')
  12. #define enter putchar('\n')
  13. //#define ivorysi
  14. #define MAXN 100005
  15. using namespace std;
  16. typedef long long int64;
  17. template<class T>
  18. void read(T &res) {
  19. res = 0;char c = getchar();T f = 1;
  20. while(c < '0' || c > '9') {
  21. if(c == '-') f = -1;
  22. c = getchar();
  23. }
  24. while(c >= '0' && c <= '9') {
  25. res = res * 10 + c - '0';
  26. c = getchar();
  27. }
  28. res *= f;
  29. }
  30. template<class T>
  31. void out(T x) {
  32. if(x < 0) {x = -x;putchar('-');}
  33. if(x >= 10) out(x / 10);
  34. putchar('0' + x % 10);
  35. }
  36. int N;
  37. int a[1005][1005];
  38. int main() {
  39. #ifdef ivorysi
  40. freopen("f1.in","r",stdin);
  41. #endif
  42. read(N);
  43. int t = 0,k = 0;
  44. for(int i = 1 ; i <= N ; ++i) {
  45. t += i;
  46. if(t >= N) {k = i;break;}
  47. }
  48. if(t != N) {puts("No");}
  49. else {
  50. puts("Yes");
  51. out(k + 1);enter;
  52. int cnt = 0;
  53. for(int j = 1 ; j <= k ; ++j) {
  54. for(int i = j ; i <= k ; ++i) {
  55. a[j][i] = ++cnt;
  56. }
  57. for(int i = j + 1 ; i <= k + 1 ; ++i) {
  58. a[i][j] = a[j][i - 1];
  59. }
  60. }
  61. for(int i = 1 ; i <= k + 1 ; ++i) {
  62. out(k);
  63. for(int j = 1 ; j <= k ; ++j) {
  64. space;out(a[i][j]);
  65. }
  66. enter;
  67. }
  68. }
  69. return 0;
  70. }

E - Equilateral

先熟练地转一下切比雪夫距离

容易发现这个三元组必然有两个在同一水平线或者同一竖直线上,合法的点一定是在某两个和坐标轴平行的条内,然后记录一下转完坐标系后的矩阵和,两两枚举所有水平线和竖直线上的所有点,然后计算合法的点

防止重复统计可以要求同一水平线上的点的三元组第三个和任两个不在同一竖直线,或者反过来

代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <vector>
  6. #define fi first
  7. #define se second
  8. #define pii pair<int,int>
  9. #define mp make_pair
  10. #define pb push_back
  11. #define space putchar(' ')
  12. #define enter putchar('\n')
  13. //#define ivorysi
  14. #define MAXN 100005
  15. using namespace std;
  16. typedef long long int64;
  17. template<class T>
  18. void read(T &res) {
  19. res = 0;char c = getchar();T f = 1;
  20. while(c < '0' || c > '9') {
  21. if(c == '-') f = -1;
  22. c = getchar();
  23. }
  24. while(c >= '0' && c <= '9') {
  25. res = res * 10 + c - '0';
  26. c = getchar();
  27. }
  28. res *= f;
  29. }
  30. template<class T>
  31. void out(T x) {
  32. if(x < 0) {x = -x;putchar('-');}
  33. if(x >= 10) out(x / 10);
  34. putchar('0' + x % 10);
  35. }
  36. int H,W;
  37. char s[305][305];
  38. int sum[605][605];
  39. vector<int> row[605],col[605];
  40. int Query1(int x1,int x2,int y) {
  41. if(x2 < x1) return 0;
  42. if(y < 1 || y > H + W) return 0;
  43. x2 = min(x2,H + W);
  44. x1 = max(x1,1);
  45. return sum[x2][y] - sum[x1 - 1][y] - sum[x2][y - 1] + sum[x1 - 1][y - 1];
  46. }
  47. int Query2(int x,int y1,int y2) {
  48. if(y2 < y1) return 0;
  49. if(x < 1 || x > H + W) return 0;
  50. y2 = min(y2,H + W);
  51. y1 = max(y1,1);
  52. return sum[x][y2] - sum[x][y1 - 1] - sum[x - 1][y2] + sum[x - 1][y1 - 1];
  53. }
  54. int main() {
  55. #ifdef ivorysi
  56. freopen("f1.in","r",stdin);
  57. #endif
  58. read(H);read(W);
  59. for(int i = 1 ; i <= H ; ++i) {
  60. scanf("%s",s[i] + 1);
  61. }
  62. for(int i = 1 ; i <= H ; ++i) {
  63. for(int j = 1 ; j <= W ; ++j) {
  64. if(s[i][j] == '#') {
  65. sum[i + j][i - j + W]++;
  66. row[i + j].pb(i - j + W);
  67. col[i - j + W].pb(i + j);
  68. }
  69. }
  70. }
  71. for(int i = 1 ; i <= H + W ; ++i) {
  72. for(int j = 1 ; j <= H + W ; ++j) {
  73. sum[i][j] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
  74. }
  75. }
  76. int64 ans = 0;
  77. for(int i = 1 ; i <= H + W ; ++i) {
  78. int s = row[i].size();
  79. sort(row[i].begin(),row[i].end());
  80. for(int j = 0 ; j < s ; ++j) {
  81. for(int k = j + 1 ; k < s ; ++k) {
  82. int l = row[i][k] - row[i][j];
  83. ans += Query2(i - l,row[i][j],row[i][k]);
  84. ans += Query2(i + l,row[i][j],row[i][k]);
  85. }
  86. }
  87. }
  88. for(int i = 1 ; i <= H + W ; ++i) {
  89. int s = col[i].size();
  90. sort(col[i].begin(),col[i].end());
  91. for(int j = 0 ; j < s ; ++j) {
  92. for(int k = j + 1 ; k < s ; ++k) {
  93. int l = col[i][k] - col[i][j];
  94. ans += Query1(col[i][j] + 1,col[i][k] - 1,i - l);
  95. ans += Query1(col[i][j] + 1,col[i][k] - 1,i + l);
  96. }
  97. }
  98. }
  99. out(ans);enter;
  100. return 0;
  101. }

F - Circular

比赛的时候没时间想了,后来把计数方案推完,我觉得这个方案真的非常假……(但我一时间没想到反例……)

居然A了?

这题的英文题解貌似咕着,感觉能赚一点访问量了

显然如果都是1的话方案是\(n!\),这个特判掉

其次这个序列必然是相同的数都在连续的一段,不能有穿插的数,例如样例3 1 4 1 5,很好想,不说了

然后我们找到1所在的段长,这肯定是序列进行的操作次数

为了方便,我们断环为链,把1扯出来作为第一个数

然后剩下的段长都不能超过这个长度,否则输出0

设段长为\(len\),当前位置的数\(i\)肯定是比\([i,i + len - 1]\)的最大值要大,这个你单调队列还是写rmq随意吧,都求出来,记为\(val[i]\)

然后对于连续一段的数\([l,r]\)这个数位\(num\),这个限制了\(num\)在某个区间里

这个区间就是\([r + 1 - len,l]\)我们计算一下这个区间里的数有几个\(val[i]\)和\(num\)相同,这个时候,假如这个值是0,那么无解

统计的时候我们记录一个\(cnt[x]\)表示\(val[i] == x\)的个数,处理成前缀和

统计的时候枚举每一个数,假如这个数有必选位置,我们乘上必选位置的个数,否则乘上\(cnt[i] - (i - 1)\)也就是\(cnt[i]\)是\(i\)能在的位置,这些位置有且仅有\(i - 1\)个被占用了

代码

  1. #include <bits/stdc++.h>
  2. #define fi first
  3. #define se second
  4. #define pii pair<int,int>
  5. #define space putchar(' ')
  6. #define enter putchar('\n')
  7. #define mp make_pair
  8. #define pb push_back
  9. //#define ivorysi
  10. #define MAXN 300005
  11. using namespace std;
  12. typedef long long int64;
  13. typedef double db;
  14. template<class T>
  15. void read(T &res) {
  16. res = 0;char c = getchar();T f = 1;
  17. while(c < '0' || c > '9') {
  18. if(c == '-') f = -1;
  19. c = getchar();
  20. }
  21. while(c >= '0' && c <= '9') {
  22. res = res * 10 + c - '0';
  23. c = getchar();
  24. }
  25. res *= f;
  26. }
  27. template<class T>
  28. void out(T x) {
  29. if(x < 0) {x = -x;putchar('-');}
  30. if(x >= 10) {
  31. out(x / 10);
  32. }
  33. putchar('0' + x % 10);
  34. }
  35. const int MOD = 998244353;
  36. int N,a[MAXN * 2],A[MAXN],st[MAXN][20],val[MAXN],len[MAXN],must[MAXN],sum[MAXN],ql,qr,cnt[MAXN];
  37. bool vis[MAXN];
  38. int inc(int a,int b) {
  39. return a + b >= MOD ? a + b - MOD : a + b;
  40. }
  41. int mul(int a,int b) {
  42. return 1LL * a * b % MOD;
  43. }
  44. int Query(int l,int r) {
  45. int t = len[r - l + 1];
  46. return max(st[l][t],st[r - (1 << t) + 1][t]);
  47. }
  48. void Move(int l,int r) {
  49. while(qr < r) sum[val[++qr]]++;
  50. while(ql < l) sum[val[ql++]]--;
  51. }
  52. void Solve() {
  53. read(N);bool all_1 = 1;
  54. for(int i = 1 ; i <= N ; ++i) {read(a[i]);a[i + N] = a[i];if(a[i] != 1) all_1 = 0;}
  55. if(all_1) {
  56. int res = 1;
  57. for(int i = 1 ; i <= N ; ++i) res = mul(res,i);
  58. out(res);enter;return;
  59. }
  60. int s = 0;
  61. for(int i = 2 ; i <= 2 * N ; ++i) {
  62. if(a[i] == 1 && a[i - 1] != 1) {
  63. s = i;
  64. break;
  65. }
  66. }
  67. if(!s) {puts("0");return;}
  68. for(int i = 1 ; i <= N ; ++i) A[i] = a[s++];
  69. int p = 1;
  70. while(A[p] == 1) ++p;
  71. --p;
  72. int l = 0;
  73. for(int i = 1 ; i <= N ; ++i) {
  74. if(A[i] != A[i - 1]) {
  75. if(vis[A[i]]) {puts("0");return;}
  76. vis[A[i]] = 1;l = 0;
  77. }
  78. ++l;
  79. if(l > p) {puts("0");return;}
  80. }
  81. for(int i = 1 ; i <= N ; ++i) st[i][0] = A[i];
  82. for(int j = 1 ; j <= 19 ; ++j) {
  83. for(int i = 1 ; i <= N ; ++i) {
  84. if(i + (1 << j) - 1 > N) break;
  85. st[i][j] = max(st[i][j - 1],st[i + (1 << j - 1)][j - 1]);
  86. }
  87. }
  88. for(int i = 2 ; i <= N ; ++i) len[i] = len[i / 2] + 1;
  89. for(int i = 1 ; i <= N ; ++i) {
  90. int r = min(i + p - 1,N);
  91. val[i] = Query(i,r);
  92. }
  93. int t = 0;ql = 1,qr = 0;
  94. for(int i = 1 ; i <= N ; ++i) {
  95. if(A[i] != A[i - 1]) {
  96. if(t) {
  97. s = max(1,i - p);
  98. Move(s,t);
  99. must[A[i - 1]] = sum[A[i - 1]];
  100. if(!sum[A[i - 1]]) {puts("0");return;}
  101. }
  102. t = i;
  103. }
  104. }
  105. s = max(1,N - p + 1);
  106. Move(s,t);
  107. must[A[N]] = sum[A[N]];
  108. if(!sum[A[N]]) {puts("0");return;}
  109. for(int i = 1 ; i <= N ; ++i) cnt[val[i]]++;
  110. for(int i = 1 ; i <= N ; ++i) cnt[i] += cnt[i - 1];
  111. int ans = 1;
  112. for(int i = 1 ; i <= N ; ++i) {
  113. if(must[i]) {ans = mul(ans,must[i]);}
  114. else ans = mul(ans,cnt[i] - (i - 1));
  115. }
  116. out(ans);enter;
  117. }
  118. int main() {
  119. #ifdef ivorysi
  120. freopen("f1.in","r",stdin);
  121. #endif
  122. Solve();
  123. return 0;
  124. }

【AtCoder】Tenka1 Programmer Contest(C - F)的更多相关文章

  1. 【AtCoder】Tenka1 Programmer Contest 2019

    Tenka1 Programmer Contest 2019 C - Stones 题面大意:有一个01序列,改变一个位置上的值花费1,问变成没有0在1右边的序列花费最少多少 直接枚举前i个都变成0即 ...

  2. 【AtCoder】Tenka1 Programmer Contest

    C - 4/N 列出个方程枚举解一下 #include <bits/stdc++.h> #define fi first #define se second #define pii pai ...

  3. 【AtCoder】AISing Programming Contest 2019

    本来以为是1199rated的..仔细一看发现是1999,所以就做了一下 这场涨分很轻松啊...为啥又没打 等pkuwc考完我一定打一场atcoder(咕咕咕,咕咕咕,咕咕咕咕咕咕咕~) 但是其实我思 ...

  4. 【AtCoder】M-SOLUTIONS Programming Contest

    M-SOLUTIONS Programming Contest A - Sum of Interior Angles #include <bits/stdc++.h> #define fi ...

  5. 【AtCoder】Yahoo Programming Contest 2019

    A - Anti-Adjacency K <= (N + 1) / 2 #include <bits/stdc++.h> #define fi first #define se se ...

  6. 【AtCoder】KEYENCE Programming Contest 2019

    A - Beginning 这个年份恐怕需要+2 #include <bits/stdc++.h> #define fi first #define se second #define p ...

  7. 【AtCoder】Dwango Programming Contest V题解

    A - Thumbnail 题意简述:给出N个数,找出N个数中和这N个数平均值绝对值最小的数 根据题意写代码即可= = #include <bits/stdc++.h> #define f ...

  8. Tenka1 Programmer Contest D - Crossing

    链接 Tenka1 Programmer Contest D - Crossing 给定\(n\),要求构造\(k\)个集合\({S_k}\),使得\(1\)到\(n\)中每个元素均在集合中出现两次, ...

  9. Tenka1 Programmer Contest C - Align

    链接 Tenka1 Programmer Contest C - Align 给定一个序列,要求重新排列最大化\(\sum_{i=2}^{i=n} |a_i-a_{i-1}|\),\(n\leq 10 ...

随机推荐

  1. String args[] 和 String[] args 有什么区别

    String args[] 和 String[] args 有什么区别 public static void main(String args[]) 或 public static void main ...

  2. 【转】Git 安装和使用教程

    git 提交 全部文件 git add .  git add xx命令可以将xx文件添加到暂存区,如果有很多改动可以通过 git add -A .来一次添加所有改变的文件.注意 -A 选项后面还有一个 ...

  3. CodeSmith自己动手写模板

    CodeSmith学习笔记------ 1.新建一个Code Smith Generator Template(C sharp) 2.一些常见标签的解释: ①外部变量: <%@ Property ...

  4. 洛谷P4198 楼房重建

    题意:给定序列,每次修改一个值,求前缀最大值的个数. 解:线段树经典应用. 每个节点维护最大值和该区间前缀最大值个数. 发现我们不用下传标记,只需要合并区间. 需要实现一个函数int ask([l r ...

  5. Java后台面试 常见问题

    Java后台面试 常见问题   从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米.百度.阿里.京东.新浪.CVTE.乐视家的研发岗offer.我找的是java后台开发,把常见的问题分享 ...

  6. 质数——6N±1法

    6N±1法求素数 任何一个自然数,总可以表示成为如下的形式之一: 6N,6N+1,6N+2,6N+3,6N+4,6N+5 (N=0,1,2,…) 显然,当N≥1时,6N,6N+2,6N+3,6N+4都 ...

  7. 数学:莫比乌斯反演-GCD计数

    Luogu3455:莫比乌斯反演进行GCD计数 莫比乌斯反演就是用来解决这一类问题的,通常f函数是要求的那个,F函数是显然的 这样利用F的结果就可以推出来f的结果 在计算结果的时候整除分快儿一下就可以 ...

  8. SQL语句(十)查询结果排序

    查询结果排序 使用ORDER BY 子句 SELECT <列名列表> FROM <表名> [WHERE 条件] ORDER BY <字段名1> [ASC|DESC] ...

  9. dedecms织梦列表页调用TAG标签并带上链接的实现方法

    在需要调用的地方添加如下代码: [field:id runphp='yes'] global $cfg_cmspath; $tags = GetTags(@me); $revalue = ''; $t ...

  10. MySql数据库表的查询操作

    http://www.cnblogs.com/whgk/p/6149009.html 优化:http://www.ihref.com/read-16422.html MYSQL常用的几种连接查询方法