博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【AtCoder】AGC006
阅读量:5013 次
发布时间:2019-06-12

本文共 11122 字,大约阅读时间需要 37 分钟。

AGC006

A - Prefix and Suffix

……

#include 
#define fi first#define se second#define pii pair
#define mp make_pair#define pb push_back#define space putchar(' ')#define enter putchar('\n')#define eps 1e-10#define MAXN 300005//#define ivorysiusing namespace std;typedef long long int64;typedef unsigned int u32;typedef double db;template
void read(T &res) { res = 0;T f = 1;char c = getchar(); 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
void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10);}int N;string s,t;void Solve() { read(N); cin >> s >> t; for(int i = N ; i >= 1 ; --i) { if(s.substr(N - i,i) == t.substr(0,i)) { out(2 * N - i);enter;return; } } out(2 * N);enter;}int main() {#ifdef ivorysi freopen("f1.in","r",stdin);#endif Solve(); return 0;}

B - Median Pyramid Easy

发现如果中间有两个目标的x那么之后这两个x可以互相扶持一直到顶(事实上这也是D做题的关键)

如何造出来呢,如果x至少有一个比它小的和比它大的

我们可以中间填-1 0 1其中0在正中间,表示x,1表示一个比x大的数,-1表示一个比x小的数

如果还有比0小的,放在1的后面,有比0大的放在-1的前面,就可以让中间两个0了

剩下的随便放就好了

#include 
#define fi first#define se second#define pii pair
#define mp make_pair#define pb push_back#define space putchar(' ')#define enter putchar('\n')#define eps 1e-10#define MAXN 100005//#define ivorysiusing namespace std;typedef long long int64;typedef unsigned int u32;typedef double db;template
void read(T &res) { res = 0;T f = 1;char c = getchar(); 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
void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10);}int N,x;int a[MAXN];vector
l,r;deque
q;void Solve() { read(N);read(x); if(x == 1 || x == 2 * N - 1) {puts("No");return;} puts("Yes"); for(int i = 1 ; i < x ; ++i) l.pb(i); for(int i = x + 1 ; i <= 2 * N - 1 ; ++i) r.pb(i); q.pb(x); bool f = 0; while(l.size() && r.size()) { if(f) { q.push_back(l.back()); q.push_front(r.back()); } else { q.push_back(r.back()); q.push_front(l.back()); } l.pop_back();r.pop_back(); f ^= 1; } if(r.size() > l.size()) swap(l,r); while(l.size()) { q.push_back(l.back()); l.pop_back(); q.push_front(l.back()); l.pop_back(); } for(int i = 0 ; i < 2 * N - 1 ; ++i) {out(q[i]);space;} enter;}int main() {#ifdef ivorysi freopen("f1.in","r",stdin);#endif Solve(); return 0;}

C - Rabbit Exercise

如果对\(x_{2}\)进行操作

那么就变成

\(x_{1},x_{3} + x_{1} - x_{2},x_{3}\)

这个需要一点想象力,觉得这种变换总需要有个不变量,或者实现了某种交换

发现交换的是2两边的差分,于是问题就可以转化成一个映射的K次幂,最后把差分归位就可以恢复出最终序列了

#include 
#define fi first#define se second#define pii pair
#define mp make_pair#define pb push_back#define space putchar(' ')#define enter putchar('\n')#define eps 1e-10#define MAXN 100005//#define ivorysiusing namespace std;typedef long long int64;typedef unsigned int u32;typedef double db;template
void read(T &res) { res = 0;T f = 1;char c = getchar(); 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
void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10);}int x[MAXN],M,N,a[MAXN];int64 l[MAXN],K;struct node { int p[MAXN]; friend node operator * (const node &a,const node &b) { node c; for(int i = 1 ; i < N ; ++i) c.p[i] = b.p[a.p[i]]; return c; }}f,ans;node fpow(node x,int64 c) { node res,t = x; for(int i = 1 ; i < N ; ++i) res.p[i] = i; while(c) { if(c & 1) res = res * t; t = t * t; c >>= 1; } return res;}void Solve() { read(N); for(int i = 1 ; i <= N ; ++i) read(x[i]); read(M);read(K); for(int i = 1 ; i < N ; ++i) a[i] = i; int t; for(int i = 1 ; i <= M ; ++i) { read(t); swap(a[t - 1],a[t]); } for(int i = 1 ; i < N ; ++i) f.p[a[i]] = i; ans = fpow(f,K); l[1] = x[1]; for(int i = 1 ; i < N ; ++i) { l[ans.p[i] + 1] = x[i + 1] - x[i]; } for(int i = 1 ; i <= N ; ++i) { l[i] += l[i - 1]; out(l[i]);enter; }}int main() {#ifdef ivorysi freopen("f1.in","r",stdin);#endif Solve(); return 0;}

D - Median Pyramid Hard

我们二分一个x表示答案应该小于等于x,把小于等于x的都标成0,大于x的都标成1

如果从左到右是1010101这样的形式,即不存在相邻两个数值是一样的,那么每次取反看看中间的位置取反\(N - 1\)次是什么就好

如果存在两个相同的

看看哪个相同(11或00)的离中间最近,最后的答案就是它

#include 
#define fi first#define se second#define pii pair
#define mp make_pair#define pb push_back#define space putchar(' ')#define enter putchar('\n')#define eps 1e-10#define MAXN 100005//#define ivorysiusing namespace std;typedef long long int64;typedef unsigned int u32;typedef double db;template
void read(T &res) { res = 0;T f = 1;char c = getchar(); 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
void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10);}int N,a[MAXN * 2],v[MAXN * 2];bool check(int x) { for(int i = 1 ; i <= 2 * N - 1 ; ++i) { v[i] = (a[i] > x); } for(int i = 1 ; i < N ; ++i) { if(v[N - i] == v[N - i + 1]) { return v[N - i] != 1; } if(v[N + i] == v[N + i - 1]) { return v[N + i] != 1; } } v[N] ^= ((N - 1) & 1); return v[N] != 1;}void Solve() { read(N); for(int i = 1 ; i <= 2 * N - 1 ; ++i) read(a[i]); int L = 2,R = 2 * N - 2; while(L < R) { int mid = (L + R) >> 1; if(check(mid)) R = mid; else L = mid + 1; } out(L);enter;}int main() {#ifdef ivorysi freopen("f1.in","r",stdin);#endif Solve(); return 0;}

E - Rotate 3x3

发现中间一列怎么动都还在中间的时候,就可以考虑一下是不是和中间位置复原的交换次数有关了

因为交换一次或者当了中间轴一次,上下顺序都会改变,我们就希望交换的次数满足能让这个数上下变成原来样子的奇偶性

因为奇数列和偶数列不交换位置,设\(inv_{e}\)是偶数列彼此交换的位置,\(flip_{e}\)是偶数列初始时需要翻转的位置,同理定义\(inv_{o}\)\(flip_{o}\)是奇数列的,他们的奇偶性可以确定

当我们交换两个偶数列

\(inv_{e}\)\(flip_{o}\)同时改变

当我们交换两个奇数列

\(inv_{o}\)\(flip_{e}\)同时改变

可以发现\(inv_{e}\)\(flip_o\)奇偶性相等是必要的,\(inv_o\)\(flip_e\)的奇偶性是相同也是必要的

这也是充分的,我们考虑我们用了所有的\(inv_e\)和所有的\(inv_o\)使得第二行数全部归位,此时\(flip_{o}\)\(flip_{e}\)都是偶数,我们给出一种构造使得我们能在不交换数原有顺序的情况下翻转两个相邻的奇数列或偶数列

\(A\)是a列的翻转

初始情况是

\(a,b,c,d,e\)

\(C,B,A,d,e\)

\(C,B,E, D,a\)

\(e,b,c,D,a\)

\(e,b,A,d,C\)

\(a,B,E,d,C\)

\(a,B,c,D,e\)

\(a,d,C,b,e\)

\(c, D,A,b,e\)

\(c,B,a,d,e\)

\(A,b,C,d,e\)

这样就可以证明了

#include 
#define fi first#define se second#define pii pair
#define mp make_pair#define pb push_back#define space putchar(' ')#define enter putchar('\n')#define eps 1e-10#define MAXN 100005//#define ivorysiusing namespace std;typedef long long int64;typedef unsigned int u32;typedef double db;template
void read(T &res) { res = 0;T f = 1;char c = getchar(); 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
void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10);}int N,a[4][MAXN],inv[2],flip[2];int tr[MAXN * 3];int lowbit(int x) {return x & (-x);}void insert(int x,int v) { while(x <= 3 * N) { tr[x] += v; x += lowbit(x); }}int query(int x) { int r = 0; while(x > 0) { r += tr[x]; x -= lowbit(x); } return r;}void Solve() { read(N); for(int i = 1 ; i <= 3 ; ++i) { for(int j = 1 ; j <= N ; ++j) read(a[i][j]); } for(int i = 1 ; i <= N ; ++i) { if(a[2][i] % 3 != 2) {puts("No");return;} if((a[2][i] / 3 + 1 & 1) != (i & 1)) {puts("No");return;} int b = a[1][i],c = a[3][i]; if(b > c) swap(b,c); if(b != a[2][i] - 1 || c != a[2][i] + 1) {puts("No");return;} if(a[2][i] - 1 == a[3][i]) flip[i & 1] ^= 1; } for(int i = 1 ; i <= N ; i += 2) { inv[i & 1] ^= query(3 * N) - query(a[2][i]) & 1; insert(a[2][i],1); } memset(tr,0,sizeof(tr)); for(int i = 2 ; i <= N ; i += 2) { inv[i & 1] ^= query(3 * N) - query(a[2][i]) & 1; insert(a[2][i],1); } if(flip[0] != inv[1]) {puts("No");return;} if(flip[1] != inv[0]) {puts("No");return;} puts("Yes");}int main() {#ifdef ivorysi freopen("f1.in","r",stdin);#endif Solve(); return 0;}

F - Blackout

一个点\((a,b)\)相当于一条边从\(a\)\(b\)

\((a,b)\)\((b,c)\)会得到一条边\((c,a)\)

显然边只会加在一个弱连通的图里,我们对每个弱连通的图分别处理

我们把这张图三色染色,如果是出边则+1否则-1,取模3

如果三色染色可以成功,但是图中三个颜色并不齐,那么这个弱连通图加不了任何边

如果三色染色成功了,三个颜色都齐了,那所有A可以往所有的B连边,所有的B可以往所有的C连边,所有的C可以往所有的A连边

如果三色染色不成功,那这个弱连通图两两之间的点都可以连边,可以有自环

#include 
#define fi first#define se second#define pii pair
#define mp make_pair#define pb push_back#define space putchar(' ')#define enter putchar('\n')#define eps 1e-10#define MAXN 100005//#define ivorysiusing namespace std;typedef long long int64;typedef unsigned int u32;typedef double db;template
void read(T &res) { res = 0;T f = 1;char c = getchar(); 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
void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10);}int N,M;struct node { int to,v,next;}E[MAXN * 2];int head[MAXN],sumE,col[MAXN];bool vis[MAXN];int cnt[5];int64 ans,s,num;bool flag = 0;void add(int u,int v,int c) { E[++sumE].to = v; E[sumE].next = head[u]; E[sumE].v = c; head[u] = sumE;}void dfs(int u) { vis[u] = 1;++num; ++cnt[col[u]]; for(int i = head[u] ; i ; i= E[i].next) { int v = E[i].to;++s; if(vis[v]) { if(col[v] != (col[u] + E[i].v + 3) % 3) flag = 1; } else { col[v] = (col[u] + E[i].v + 3) % 3; dfs(v); } }}void Solve() { read(N);read(M); int a,b; for(int i = 1 ; i <= M ; ++i) { read(a);read(b); add(a,b,1); add(b,a,-1); } for(int i = 1 ; i <= N ; ++i) { if(!vis[i]) { memset(cnt,0,sizeof(cnt)); col[i] = 0; s = 0;num = 0; flag = 0;dfs(i); if(!flag) { if(!cnt[0] || !cnt[1] || !cnt[2]) { ans += s / 2; } else { ans += 1LL * cnt[1] * cnt[0]; ans += 1LL * cnt[2] * cnt[1]; ans += 1LL * cnt[2] * cnt[0]; } } else { ans += 1LL * num * num; } } } out(ans);enter;}int main() {#ifdef ivorysi freopen("f1.in","r",stdin);#endif Solve(); return 0;

转载于:https://www.cnblogs.com/ivorysi/p/10880427.html

你可能感兴趣的文章
两个Html页面之间值得传递
查看>>
EasyUI datagrid 的多条件查询
查看>>
Mac升级bash到最新版本
查看>>
利用vagrant打包系统--制作自己的box
查看>>
美女与硬币问题
查看>>
计算几何算法概览 (转)
查看>>
Notepad++的ftp远程编辑功能
查看>>
数据库多对多关联表(Python&MySQL)
查看>>
[实变函数]1.2 集合的运算
查看>>
第06天
查看>>
设计模式的征途—5.原型(Prototype)模式
查看>>
iOS10 app连接不上网络的问题
查看>>
结对开发之电梯调度最终稿(徐梦迪&刘博)
查看>>
simple java mail
查看>>
信息建模
查看>>
Mybatis 数据库物理分页插件 PageHelper
查看>>
虚函数、纯虚函数详解
查看>>
z-stack中数据的发送,广播、组播、点对点
查看>>
Practial Vim 学习笔记一
查看>>
.NET中使用js实现百度搜索下拉提示效果[不是局部刷新,呜呜。。]
查看>>