枚舉便可node
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define space putchar('\n') #define enter putchar(' ') //#define ivorysi using namespace std; typedef long long int64; 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){putchar('-');x = -x;} if(x >= 10) out(x / 10); putchar('0' + x % 10); } int N; int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif read(N); int ans = 0x7fffffff; for(int i = 1 ; i < N ; ++i) { int A = i,B = N - i; int tmp = 0; while(A) {tmp += A % 10;A /= 10;} while(B) {tmp += B % 10;B /= 10;} ans = min(ans,tmp); } out(ans);enter; }
枚舉有幾個A,能夠算出有幾個B
能夠看做給序列染兩次色(每一個塊能夠有兩種顏色),被同時染了紅和藍的就是綠色算就行了c++
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define space putchar('\n') #define enter putchar(' ') #define MAXN 300005 //#define ivorysi using namespace std; typedef long long int64; 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){putchar('-');x = -x;} if(x >= 10) out(x / 10); putchar('0' + x % 10); } const int MOD = 998244353; int N,fac[MAXN],invfac[MAXN],inv[MAXN]; int64 A,B,K; int mul(int a,int b) { return 1LL * a * b % MOD; } int inc(int a,int b) { return a + b >= MOD ? a + b - MOD : a + b; } int C(int n,int m) { if(m > n) return 0; return mul(fac[n],mul(invfac[m],invfac[n - m])); } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif read(N);read(A);read(B);read(K); inv[1] = 1; for(int i = 2 ; i <= N ; ++i) { inv[i] = mul(inv[MOD % i],MOD - MOD / i); } fac[0] = invfac[0] = 1; for(int i = 1 ; i <= N ; ++i) { fac[i] = mul(fac[i - 1],i); invfac[i] = mul(invfac[i - 1],inv[i]); } int ans = 0; for(int i = 0 ; i <= N ; ++i) { if(K < i * A) break; if((K - i * A) % B != 0) continue; int s = i,t = (K - i * A) / B; ans = inc(ans,mul(C(N,s),C(N,t))); } out(ans);enter; }
每次都往最左和最右拉
枚舉第一次是往左仍是往右git
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define space putchar('\n') #define enter putchar(' ') #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; 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){putchar('-');x = -x;} if(x >= 10) out(x / 10); putchar('0' + x % 10); } const int MOD = 998244353; int N,ans; pii S[MAXN]; int id[2][MAXN]; bool vis[MAXN]; bool cmp1(int a,int b) { return S[a].fi < S[b].fi; } bool cmp2(int a,int b) { return S[a].se < S[b].se; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif read(N); for(int i = 1 ; i <= N ; ++i) { read(S[i].fi);read(S[i].se); id[0][i] = i;id[1][i] = i; } sort(id[0] + 1,id[0] + N + 1,cmp1); sort(id[1] + 1,id[1] + N + 1,cmp2); int64 ans = 0; memset(vis,0,sizeof(vis)); int p[2];p[0] = N,p[1] = 1; int pos = 0;int64 tmp = 0; if(S[id[0][N]].fi > 0) { vis[id[0][p[0]]] = 1;--p[0]; tmp += abs(S[id[0][N]].fi - pos); pos = S[id[0][N]].fi; int cur = 1; while(1) { if(cur == 1) { while(p[cur] <= N && vis[id[cur][p[cur]]]) ++p[cur]; if(p[cur] > N) break; if(S[id[cur][p[cur]]].se >= pos) break; tmp += abs(S[id[cur][p[cur]]].se - pos); pos = S[id[cur][p[cur]]].se; vis[id[cur][p[cur]]] = 1; } else { while(p[cur] >= 1 && vis[id[cur][p[cur]]]) --p[cur]; if(p[cur] < 1) break; if(S[id[cur][p[cur]]].fi <= pos) break; tmp += abs(S[id[cur][p[cur]]].fi - pos); pos = S[id[cur][p[cur]]].fi; vis[id[cur][p[cur]]] = 1; } cur ^= 1; } tmp += abs(pos); } ans = max(ans,tmp); memset(vis,0,sizeof(vis)); pos = 0;tmp = 0;p[0] = N;p[1] = 1; if(S[id[1][1]].se < 0) { vis[id[1][1]] = 1;++p[1]; tmp += abs(S[id[1][1]].se - pos); pos = S[id[1][1]].se; int cur = 0; while(1) { if(cur == 1) { while(p[cur] <= N && vis[id[cur][p[cur]]]) ++p[cur]; if(p[cur] > N) break; if(S[id[cur][p[cur]]].se >= pos) break; tmp += abs(S[id[cur][p[cur]]].se - pos); pos = S[id[cur][p[cur]]].se; vis[id[cur][p[cur]]] = 1; } else { while(p[cur] >= 1 && vis[id[cur][p[cur]]]) --p[cur]; if(p[cur] < 1) break; if(S[id[cur][p[cur]]].fi <= pos) break; tmp += abs(S[id[cur][p[cur]]].fi - pos); pos = S[id[cur][p[cur]]].fi; vis[id[cur][p[cur]]] = 1; } cur ^= 1; } tmp += abs(pos); } ans = max(ans,tmp); out(ans);enter; }
咱們根據\(D_1\)和\(D_2\)連邊,會獲得兩個二分圖
爲何是二分圖呢
對於\(D\)是奇數來講,\((x,y)\)和\((x + s,y + t)\)連邊,咱們很容易發現這兩個點橫縱座標加和奇偶性不一樣
對於\(D\)是偶數來講,仍是根據奇偶性染色,咱們發現邊只在顏色相同的塊裏有,咱們把\(\sqrt{2}\)當單位長度,再一次對每一個聯通塊二分圖染色,這樣不斷消去2,最後就會獲得一個二分圖spa
那麼每一個點在兩個圖裏一共四種搭配,那麼根據鴿巢原理,最多的那個顏色必然有超過\(N^2\)個點code
#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 MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; 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){putchar('-');x = -x;} if(x >= 10) out(x / 10); putchar('0' + x % 10); } int N,D[2]; struct node { int to,next; }E[10000005]; int head[400005],sumE,dx[] = {-1,-1,1,1},dy[] = {1,-1,-1,1}; int col[400005],cr[400005],cnt[5]; int to_int(pii p) { return p.fi * 2 * N + p.se; } void add(int u,int v) { E[++sumE].to = v; E[sumE].next = head[u]; head[u] = sumE; } void dfs(int u) { if(col[u] == -1) col[u] = 0; for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(col[v] == -1) {col[v] = col[u] ^ 1;dfs(v);} } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif read(N);read(D[0]);read(D[1]); for(int t = 0 ; t <= 1 ; ++t) { memset(head,0,sizeof(head));sumE = 0; for(int x = 0 ; x < 2 * N ; ++x) { if(D[t] < x * x) break; int y = sqrt(D[t] - x * x); if(y * y != D[t] - x * x) continue; for(int i = 0 ; i < 2 * N ; ++i) { for(int j = 0 ; j < 2 * N ; ++j) { for(int k = 0 ; k < 4 ; ++k) { int tx = i + dx[k] * x,ty = j + dy[k] * y; if(tx >= 0 && tx < 2 * N && ty >= 0 && ty < 2 * N) { add(to_int(mp(i,j)),to_int(mp(tx,ty))); } } } } } memset(col,-1,sizeof(col)); for(int i = 0 ; i < 4 * N * N ; ++i) { if(col[i] == -1) dfs(i); cr[i] = cr[i] << 1 | col[i]; } } for(int i = 0 ; i < 4 * N * N ; ++i) ++cnt[cr[i]]; int t = 0; for(int i = 1 ; i < 4 ; ++i) { if(cnt[i] > cnt[t]) t = i; } int a = N * N; for(int i = 0 ; i < 4 * N * N ; ++i) { if(!a) break; if(cr[i] == t) { out(i / (2 * N));space;out(i % (2 * N));enter; --a; } } }
答案最大是\(min(c_i,2)\)的和,\(c_i\)是每條邊被覆蓋了幾回get
構造方法是每次選一個葉子u
找到連着u的惟一一條邊v,\((u,v)\)若是這條邊覆蓋的鏈有1條或0條,那麼就刪掉u
不然將全部覆蓋着u的鏈兩兩組合\((u,a)\)和\((u,b)\)變成\((a,b)\)經過\((a,b)\)的方向來判斷\((u,a)\)和\((u,b)\)的方向it
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define space putchar(' ') #define enter putchar('\n') #define MAXN 4005 #define mp make_pair #define pb push_back //#define ivorysi using namespace std; typedef long long int64; 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,next; }E[MAXN * 2]; int head[MAXN],sumE,d[MAXN],dep[MAXN],fa[MAXN],cnt[MAXN]; void add(int u,int v) { E[++sumE].to = v; E[sumE].next = head[u]; head[u] = sumE; } void dfs(int u) { dep[u] = dep[fa[u]] + 1; for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(v != fa[u]) { fa[v] = u; dfs(v); } } } int col(int u,int v) { if(dep[u] < dep[v]) swap(u,v); while(dep[u] != dep[v]) { ++cnt[u]; u = fa[u]; } while(u != v) { ++cnt[u];++cnt[v]; u = fa[u];v = fa[v]; } } vector<pii > Process(vector<pii> pth) { int x = 0; for(int i = 1 ; i <= N ; ++i) { if(d[i] == 1) { x = i;break; } } d[x]--;int u = 0; for(int i = head[x] ; i ; i = E[i].next) { int v = E[i].to; if(d[v]) { --d[v];u = v;break; } } if(!u) return pth; vector<pii > pass,npth; vector<int> id; id.clear();pass.clear();npth.clear(); int pos[2005]; int t,h; memset(pos,-1,sizeof(pos)); for(int i = 0 ; i < pth.size() ; ++i){ if(pth[i].fi == x && pth[i].se != x) { pass.pb(pth[i]);id.pb(i); } else if(pth[i].fi != x && pth[i].se == x) { swap(pth[i].fi,pth[i].se); pass.pb(pth[i]);id.pb(i); } else { npth.pb(pth[i]); pos[i] = npth.size() - 1; } } t = npth.size(); if(!pass.size()) return Process(pth); bool flag = 0; for(int i = 0 ; i < pass.size() ; i += 2) { if(i + 1 >= pass.size()) break; if(pass[i].se == pass[i + 1].se) swap(pth[id[i]].fi,pth[id[i]].se); npth.pb(mp(pass[i].se,pass[i + 1].se)); pos[id[i]] = npth.size() - 1; pos[id[i + 1]] = npth.size() - 1; } if(pass.size() & 1) { flag = 1; h = pass.size() - 1; npth.pb(mp(u,pass[h].se)); pos[id[h]] = npth.size() - 1; } npth = Process(npth); for(int i = 0 ; i < pth.size() ; ++i) { if(pos[i] < t) {pth[i] = npth[pos[i]];} else { if(flag && i == id[h]) { if(npth[pos[i]].fi != u) swap(pth[i].fi,pth[i].se); } else { if(npth[pos[i]].fi != npth[pos[i]].se && npth[pos[i]].fi == pth[i].se) swap(pth[i].fi,pth[i].se); } } } return pth; } void Solve() { read(N);read(M); int a,b; for(int i = 1 ; i < N ; ++i) { read(a);read(b); add(a,b);add(b,a); ++d[a];++d[b]; } dfs(1); vector<pii > v; for(int i = 1 ; i <= M ; ++i) { read(a);read(b); v.pb(mp(a,b));col(a,b); } v = Process(v); int ans = 0; for(int i = 1 ; i <= N ; ++i) ans += min(2,cnt[i]); out(ans);enter; for(int i = 0 ; i < v.size() ; ++i) { out(v[i].fi);space;out(v[i].se);enter; } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
咱們能夠從高位到低位處理每一位的移動io
若是兩位是(1,1),咱們用一個棧從棧頂到棧底下標遞增維護\((0,1)\)和\((1,0)\)的形狀
進位分紅三種
11,s和t都進位
10,s進位,t不進位
01,s不進位,t進位class
若是有11,咱們看看走的步數能不能走到一個\((1,0)\)或\((0,1)\),再計算下一種進位方式
若是有10,或01,咱們看看下一個形狀是否是就在它的下一位,而後再計算下一種計算方式原理
若是都不成立,那麼若是進位是11,移動到最後的位置並把這一位都寫成1
若是進位是10和01,那麼放進棧裏
每次走兩步必然會少一個元素,因此複雜度是\(O(n)\)的
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define space putchar(' ') #define enter putchar('\n') #define MAXN 2000005 #define mp make_pair #define pb push_back //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; 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); } struct node { int id,par; }sta[MAXN],tmp[MAXN]; int N,M,K,top,cnt,ns[MAXN],nt[MAXN],as[MAXN],at[MAXN]; char s[MAXN],t[MAXN]; void Solve() { read(N);read(M);read(K); scanf("%s",s + 1);scanf("%s",t + 1); reverse(s + 1,s + N + 1);reverse(t + 1,t + M + 1); for(int i = 1 ; i <= N ; ++i) ns[i] = s[i] - '0'; for(int i = 1 ; i <= M ; ++i) nt[i] = t[i] - '0'; int T = max(N,M); for(int i = T ; i >= 1 ; --i) { if(ns[i] == 1 && nt[i] == 1) { int op = K,pos = i,x = 3;cnt = 0; while(top) { if(x == 3) { if(op >= sta[top].id - pos) { op -= sta[top].id - pos; pos = sta[top].id; tmp[++cnt] = (node){pos,x ^ sta[top].par}; x = x & sta[top].par; } else break; } else if(x != 0){ if(sta[top].id == pos + 1) { pos = sta[top].id; if(x ^ sta[top].par) x = 3; else x = x & sta[top].par; } else break; } else break; --top; } if(x != 0 && x != 3) { ++pos; tmp[++cnt] = (node){pos,x}; } else if(x) { pos += op; as[pos] = at[pos] = 1; } for(int j = cnt ; j >= 1 ; --j) sta[++top] = tmp[j]; } else { if(ns[i] || nt[i]) { sta[++top] = (node){i,ns[i] << 1 | nt[i]}; } } } for(int i = 1 ; i <= top ; ++i) { as[sta[i].id] = (sta[i].par >> 1) & 1; at[sta[i].id] = sta[i].par & 1; } int c = T + K; while(as[c] == 0) --c; for(int i = c ; i >= 1 ; --i) {out(as[i]);} enter; c = T + K; while(at[c] == 0) --c; for(int i = c ; i >= 1 ; --i) {out(at[i]);} enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }