……node
#include <bits/stdc++.h> #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 eps 1e-10 #define MAXN 300005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> 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<class T> 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; }
发现若是中间有两个目标的x那么以后这两个x能够互相扶持一直到顶(事实上这也是D作题的关键)c++
如何造出来呢,若是x至少有一个比它小的和比它大的spa
咱们能够中间填-1 0 1其中0在正中间,表示x,1表示一个比x大的数,-1表示一个比x小的数code
若是还有比0小的,放在1的后面,有比0大的放在-1的前面,就可让中间两个0了ip
剩下的随便放就行了ci
#include <bits/stdc++.h> #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 eps 1e-10 #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> 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<class T> 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<int> l,r; deque<int> 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; }
若是对\(x_{2}\)进行操做get
那么就变成string
\(x_{1},x_{3} + x_{1} - x_{2},x_{3}\)it
这个须要一点想象力,以为这种变换总须要有个不变量,或者实现了某种交换class
发现交换的是2两边的差分,因而问题就能够转化成一个映射的K次幂,最后把差分归位就能够恢复出最终序列了
#include <bits/stdc++.h> #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 eps 1e-10 #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> 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<class T> 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; }
咱们二分一个x表示答案应该小于等于x,把小于等于x的都标成0,大于x的都标成1
若是从左到右是1010101这样的形式,即不存在相邻两个数值是同样的,那么每次取反看看中间的位置取反\(N - 1\)次是什么就好
若是存在两个相同的
看看哪一个相同(11或00)的离中间最近,最后的答案就是它
#include <bits/stdc++.h> #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 eps 1e-10 #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> 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<class T> 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; }
发现中间一列怎么动都还在中间的时候,就能够考虑一下是否是和中间位置复原的交换次数有关了
由于交换一次或者当了中间轴一次,上下顺序都会改变,咱们就但愿交换的次数知足能让这个数上下变成原来样子的奇偶性
由于奇数列和偶数列不交换位置,设\(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 <bits/stdc++.h> #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 eps 1e-10 #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> 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<class T> 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; }
一个点\((a,b)\)至关于一条边从\(a\)到\(b\)
\((a,b)\)到\((b,c)\)会获得一条边\((c,a)\)
显然边只会加在一个弱连通的图里,咱们对每一个弱连通的图分别处理
咱们把这张图三色染色,若是是出边则+1不然-1,取模3
若是三色染色能够成功,可是图中三个颜色并不齐,那么这个弱连通图加不了任何边
若是三色染色成功了,三个颜色都齐了,那全部A能够往全部的B连边,全部的B能够往全部的C连边,全部的C能够往全部的A连边
若是三色染色不成功,那这个弱连通图两两之间的点均可以连边,能够有子环
#include <bits/stdc++.h> #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 eps 1e-10 #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> 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<class T> 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;