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. NOIP2017逛公园(park)解题报告

    park作为今年noipday1最后一道题还是相比前面几道题还是有点难度的 首先你可以思考一下,第一天dp不见了,再看一下这题,有向图,看起来就比较像一个dp,考虑dp方程,首先肯定有一维是到哪个节点 ...

  2. c++函数写的都对,还是说incompatible或者not found的解决办法

    vs2010,c++,定义了一个函数如下,在BianHuanYuDib.h文件中: 在BianHuanYuDib.cpp中: 写的完全正确,但还是会报错: 很明显,连std都报错了,一般不是真的有很大 ...

  3. 40+ 个非常有用的 Oracle 查询语句

    40+ 个非常有用的 Oracle 查询语句,主要涵盖了日期操作,获取服务器信息,获取执行状态,计算数据库大小等等方面的查询.这些是所有 Oracle 开发者都必备的技能,所以快快收藏吧! 日期/时间 ...

  4. sso接口的调用

    之前一直想sso接口已经写好了,登录注册功能是怎么调用的呢?原来在登录注册的jsp页面实现的接口的调用,页面的校验和验证功能在jsp页面即可实现. 注册页面: <%@ page language ...

  5. CGI浏览器与服务器的交互

    一直在做项目,跟着写前端后端,却没有思考一个问题:前端和后端为什么能够进行通信?为什么能够将HTML页面的内容传输给后台,然后又将结果反馈给前端? 寒假偶尔看到了这个问题,也解决了我的疑惑,这是基于C ...

  6. arcgis创建渔网

    创建渔网 1.     ArcToolbox > Data Management Tools > Feature Class > Create Finshnet.选择输出要素位置,模 ...

  7. Java SSM框架之MyBatis3(六)MyBatis之参数传递

    一.单个参数  StudentParamsMapper package cn.cnki.ref.mapper; import cn.cnki.ref.pojo.Student; public inte ...

  8. CSS media--(来自网易)

    概述 通过媒体查询为不同的设备和大小配置不同的样式.代码展示 /* media */ /* 横屏 */ @media screen and (orientation:landscape){ } /* ...

  9. BZOJ2428 均分数据

    2428: [HAOI2006]均分数据 Time Limit: 5 Sec  Memory Limit: 128 MB Description 已知N个正整数:A1.A2.…….An .今要将它们分 ...

  10. 20155315 2016-2017-2 《Java程序设计》第七周学习总结

    教材学习内容总结 第12章 Lambda语法 Lambda定义 一个不用被绑定到一个标识符上,并且可能被调用的函数. 在只有Lambda表达式的情况下,参数的类型必须写出来,如果有目标类型的话,在编译 ...