C - Align

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

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

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

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

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

如果长度为偶数

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

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

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
//#define ivorysi
#define MAXN 100005
using namespace std;
typedef long long int64;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
int N;
int A[MAXN];
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
read(N);
for(int i = 1 ; i <= N ; ++i) read(A[i]);
sort(A + 1,A + N + 1);
if(N & 1) {
int t = N / 2 + 1;
int L = 1,R = N;int64 res = 0;
for(int i = 1 ; i <= t - 2; ++i) {
res -= 2 * A[i];
}
res = res - A[t - 1] - A[t];
for(int i = t + 1 ; i <= N ; ++i) res += 2 * A[i];
int64 tmp = 0;
t = N - (N / 2 + 1) + 1;
for(int i = N ; i >= t + 2 ; --i) tmp += 2 * A[i];
tmp += A[t + 1] + A[t];
for(int i = 1 ; i < t ; ++i) tmp -= 2 * A[i];
res = max(res,tmp);
out(res);enter;
}
else {
int L = 1,R = N;
int64 res = 0;
for(int i = 1 ; i <= N - 2 ; ++i) {
if(i & 1) res -= 2 * A[L++];
else res += 2 * A[R--];
}
res += A[R] - A[L];
out(res);enter;
}
return 0;
}

D - Crossing

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

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

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
//#define ivorysi
#define MAXN 100005
using namespace std;
typedef long long int64;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
int N;
int a[1005][1005];
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
read(N);
int t = 0,k = 0;
for(int i = 1 ; i <= N ; ++i) {
t += i;
if(t >= N) {k = i;break;}
}
if(t != N) {puts("No");}
else {
puts("Yes");
out(k + 1);enter;
int cnt = 0;
for(int j = 1 ; j <= k ; ++j) {
for(int i = j ; i <= k ; ++i) {
a[j][i] = ++cnt;
}
for(int i = j + 1 ; i <= k + 1 ; ++i) {
a[i][j] = a[j][i - 1];
}
}
for(int i = 1 ; i <= k + 1 ; ++i) {
out(k);
for(int j = 1 ; j <= k ; ++j) {
space;out(a[i][j]);
}
enter;
}
}
return 0;
}

E - Equilateral

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

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

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

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
//#define ivorysi
#define MAXN 100005
using namespace std;
typedef long long int64;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
int H,W;
char s[305][305];
int sum[605][605];
vector<int> row[605],col[605];
int Query1(int x1,int x2,int y) {
if(x2 < x1) return 0;
if(y < 1 || y > H + W) return 0;
x2 = min(x2,H + W);
x1 = max(x1,1);
return sum[x2][y] - sum[x1 - 1][y] - sum[x2][y - 1] + sum[x1 - 1][y - 1];
}
int Query2(int x,int y1,int y2) {
if(y2 < y1) return 0;
if(x < 1 || x > H + W) return 0;
y2 = min(y2,H + W);
y1 = max(y1,1);
return sum[x][y2] - sum[x][y1 - 1] - sum[x - 1][y2] + sum[x - 1][y1 - 1];
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
read(H);read(W);
for(int i = 1 ; i <= H ; ++i) {
scanf("%s",s[i] + 1);
}
for(int i = 1 ; i <= H ; ++i) {
for(int j = 1 ; j <= W ; ++j) {
if(s[i][j] == '#') {
sum[i + j][i - j + W]++;
row[i + j].pb(i - j + W);
col[i - j + W].pb(i + j);
}
}
}
for(int i = 1 ; i <= H + W ; ++i) {
for(int j = 1 ; j <= H + W ; ++j) {
sum[i][j] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
}
}
int64 ans = 0;
for(int i = 1 ; i <= H + W ; ++i) {
int s = row[i].size();
sort(row[i].begin(),row[i].end());
for(int j = 0 ; j < s ; ++j) {
for(int k = j + 1 ; k < s ; ++k) {
int l = row[i][k] - row[i][j];
ans += Query2(i - l,row[i][j],row[i][k]);
ans += Query2(i + l,row[i][j],row[i][k]);
}
}
}
for(int i = 1 ; i <= H + W ; ++i) {
int s = col[i].size();
sort(col[i].begin(),col[i].end());
for(int j = 0 ; j < s ; ++j) {
for(int k = j + 1 ; k < s ; ++k) {
int l = col[i][k] - col[i][j];
ans += Query1(col[i][j] + 1,col[i][k] - 1,i - l);
ans += Query1(col[i][j] + 1,col[i][k] - 1,i + l);
}
}
}
out(ans);enter;
return 0;
}

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\)个被占用了

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define space putchar(' ')
#define enter putchar('\n')
#define mp make_pair
#define pb push_back
//#define ivorysi
#define MAXN 300005
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
const int MOD = 998244353;
int N,a[MAXN * 2],A[MAXN],st[MAXN][20],val[MAXN],len[MAXN],must[MAXN],sum[MAXN],ql,qr,cnt[MAXN];
bool vis[MAXN];
int inc(int a,int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
return 1LL * a * b % MOD;
}
int Query(int l,int r) {
int t = len[r - l + 1];
return max(st[l][t],st[r - (1 << t) + 1][t]);
}
void Move(int l,int r) {
while(qr < r) sum[val[++qr]]++;
while(ql < l) sum[val[ql++]]--;
}
void Solve() {
read(N);bool all_1 = 1;
for(int i = 1 ; i <= N ; ++i) {read(a[i]);a[i + N] = a[i];if(a[i] != 1) all_1 = 0;}
if(all_1) {
int res = 1;
for(int i = 1 ; i <= N ; ++i) res = mul(res,i);
out(res);enter;return;
}
int s = 0;
for(int i = 2 ; i <= 2 * N ; ++i) {
if(a[i] == 1 && a[i - 1] != 1) {
s = i;
break;
}
}
if(!s) {puts("0");return;}
for(int i = 1 ; i <= N ; ++i) A[i] = a[s++];
int p = 1;
while(A[p] == 1) ++p;
--p;
int l = 0;
for(int i = 1 ; i <= N ; ++i) {
if(A[i] != A[i - 1]) {
if(vis[A[i]]) {puts("0");return;}
vis[A[i]] = 1;l = 0;
}
++l;
if(l > p) {puts("0");return;}
}
for(int i = 1 ; i <= N ; ++i) st[i][0] = A[i];
for(int j = 1 ; j <= 19 ; ++j) {
for(int i = 1 ; i <= N ; ++i) {
if(i + (1 << j) - 1 > N) break;
st[i][j] = max(st[i][j - 1],st[i + (1 << j - 1)][j - 1]);
}
}
for(int i = 2 ; i <= N ; ++i) len[i] = len[i / 2] + 1;
for(int i = 1 ; i <= N ; ++i) {
int r = min(i + p - 1,N);
val[i] = Query(i,r);
}
int t = 0;ql = 1,qr = 0;
for(int i = 1 ; i <= N ; ++i) {
if(A[i] != A[i - 1]) {
if(t) {
s = max(1,i - p);
Move(s,t);
must[A[i - 1]] = sum[A[i - 1]];
if(!sum[A[i - 1]]) {puts("0");return;}
}
t = i;
}
}
s = max(1,N - p + 1);
Move(s,t);
must[A[N]] = sum[A[N]];
if(!sum[A[N]]) {puts("0");return;}
for(int i = 1 ; i <= N ; ++i) cnt[val[i]]++;
for(int i = 1 ; i <= N ; ++i) cnt[i] += cnt[i - 1];
int ans = 1;
for(int i = 1 ; i <= N ; ++i) {
if(must[i]) {ans = mul(ans,must[i]);}
else ans = mul(ans,cnt[i] - (i - 1));
}
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

【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. Spring中ClassPathXmlApplication与FileSystemXmlApplicationContext的区别以及ClassPathXmlApplicationContext 的具体路径

    一.ClassPathXmlApplicationContext 的具体路径 String s[] = System.getProperty("java.class.path"). ...

  2. MT【103】二阶递推找规律

    评:如果直接找$a_n$的二阶递推式:$a_{n+2}-2\sqrt{2}a_{n+1}-a_n=0$有根号,不利于估计尾数.

  3. 前端学习 -- Css -- 定义列表

    定义列表用来对一些词汇或内容进行定义 使用dl来创建一个定义列表 dl中有两个子标签 dt : 被定义的内容 dd : 对定义内容的描述 同样dl和ul和ol之间都可以互相嵌套 <!DOCTYP ...

  4. webpack:代码分割与按需加载

    代码分割就是我们根据实际业务需求将代码进行分割,然后在合适的时候在将其加载进入文档中. 代码中总有些东西我们希望拆分开来,比如: 使用概率较低的模块,希望后期使用的时候异步加载 框架代码,希望能利用浏 ...

  5. thinkphp自学笔记

    什么是MVC? M:编写模型类-对数据进行操作 用作数据处理 V:编写HTML文件-将页面显示出来 网页视图 C:编写类文件 用作逻辑处理 ThinkPHP的MVC的特点是什么: 它比较灵活并不依赖 ...

  6. 《高性能MySQL》——第五章创建高性能索引

    1.创建索引基本语法格 在MySQL中,在已经存在的表上,可以通过ALTER TABLE语句直接为表上的一个或几个字段创建索引.基本语法格式如下: ALTER TABLE 表名 ADD [UNIQUE ...

  7. [整理]IE11中的WebGL探秘:渲染速度超Chrome

    http://www.csdn.net/article/2013-12-19/2817854-IE11-WebGL-and-more 摘要:IE11开始支持WebGL,并且效果非常好,IE11的Web ...

  8. ASP.Net巧用窗体母版页

    背景:每个网页的基本框架结构类似: 浏览网站的时候会发现,好多网站中,每个网页的基本框架都是一样的,比如,最上面都是网站的标题,中间是内容,最下面是网站的版权.开发提供商等信息: 在这些网页中,表头. ...

  9. CSS-3 渐变的使用

    CSS3 渐变(gradients)可以让您在两个或多个指定的颜色之间显示平稳的过渡. 以前,您必须使用图像来实现这些效果.但是,通过使用 CSS3 渐变(gradients),您可以减少下载的事件和 ...

  10. 20155210潘滢昊 2016-2017-2 《Java程序设计》第6周学习总结

    20155210 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 流(Stream)是对「输入输出」的抽象,注意「输入输出」是相对程序而言的 InputStr ...