看兩我的相遇的時候誰先手便可,相遇以後第一個移動的人必輸c++
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define pdi pair<db,int> #define mp make_pair #define pb push_back #define enter putchar('\n') #define space putchar(' ') #define eps 1e-8 #define mo 974711 #define MAXN 2005 //#define ivorysi 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); } int N,A,B; int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif read(N);read(A);read(B); int t = abs(B - A - 1); if(t & 1) puts("Alice"); else puts("Borys"); return 0; }
二分直接判斷便可spa
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define pdi pair<db,int> #define mp make_pair #define pb push_back #define enter putchar('\n') #define space putchar(' ') #define eps 1e-8 #define mo 974711 #define MAXN 100005 //#define ivorysi 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); } int K; int64 A[MAXN]; int64 check(int64 x) { for(int i = 1 ; i <= K ; ++i) { x -= x % A[i]; } return x; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif read(K); for(int i = 1 ; i <= K ; ++i) read(A[i]); int64 L = 2,R = 1e18; while(L < R) { int64 mid = (L + R) >> 1; if(check(mid) >= 2) R = mid; else L = mid + 1; } if(check(R) != 2) {puts("-1");return 0;} out(R);space; R = 1e18; while(L < R) { int64 mid = (L + R + 1) >> 1; if(check(mid) <= 2) L = mid; else R = mid - 1; } out(R);enter; }
咱們把子序列兩兩配對指針
也就是一個子序列選了其中的k個,另外一個子序列選了其中的n - k個,進行配對code
顯然咱們一個對內的子序列,確定一個小於等於\(\frac{sum[n]}{2}\)ci
另外一個大於等於\(\frac{sum[n]}{2}\)rem
因爲全集沒有配對,因此確定中位數就是大於等於\(\frac{sum[n]}{2}\)的第一個字符串
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define pdi pair<db,int> #define mp make_pair #define pb push_back #define enter putchar('\n') #define space putchar(' ') #define eps 1e-8 #define mo 974711 #define MAXN 200005 //#define ivorysi 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); } int N,a[MAXN],s,cur; bitset<4000005> dp[2]; void Solve() { read(N); for(int i = 1 ; i <= N ; ++i) {read(a[i]);s += a[i];} dp[cur].reset(); dp[cur][0] = 1; for(int i = 1 ; i <= N ; ++i) { dp[cur ^ 1] = (dp[cur] << a[i]) | dp[cur]; cur ^= 1; } for(int i = (s - 1) / 2 + 1; i <= s ; ++i) { if(dp[cur][i]) { out(i);enter;return; } } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
過於噁心的分類討論題
首先咱們用二分求出最小的k知足題意
求法能夠是默認把A儘量按k分塊而後往能放的空隙裏放B,以後默認把B儘量按k分塊而後能放的空隙裏放Aget
以後呢,咱們特判掉A和B分的段數不相等的狀況
也就是A是1 1 1 1,B儘量按k分塊
B是1 1 1 1,A儘量按k分塊string
以後A和B的段數就相等了
前面確定是A有k個B有1個A有k個B有1個
後面確定是A有1個B有k個A有1個B有k個
咱們二分一個二者的段數it
要求A第一個不爲k的地方不能夠在B第一個不爲k以前兩個
且長度最大
能夠二分
而後咱們把A的每段長度求出來,相同長度的記錄一個重複次數
B同理
以後咱們拿兩個指針每段合併
合併的時候同時求一下這段若是要輸出某一部分是哪裏
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define pdi pair<db,int> #define pll pair<int64,int64> #define mp make_pair #define pb push_back #define enter putchar('\n') #define space putchar(' ') #define eps 1e-8 #define mo 974711 #define MAXN 200005 //#define ivorysi 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); } int64 A,B,C,D,ML; vector<pll > vA,vB; bool check(int64 a,int64 b,int64 k) { int64 t = (a - 1) / k; if(b < t) return false; t += 2; if(b > t * k) return false; return true; } void Process(int64 l,int64 r) { int p = 0,q = 0; int64 len = 1; int64 c = 0; while(len <= ML) { int64 t = min(vA[p].se,vB[q].se); vA[p].se -= t;vB[q].se -= t; if(len >= l) { int64 k = t; while(k--) { for(int64 i = 1 ; i <= vA[p].fi ; ++i) { putchar('A');++c; if(c == r - l + 1) return; } for(int64 i = 1 ; i <= vB[q].fi ; ++i) { putchar('B');++c; if(c == r - l + 1) return; } } } else if(len + t * (vA[p].fi + vB[q].fi) - 1 >= l){ int64 k = (l - len) % (vA[p].fi + vB[q].fi) + 1; int64 h = t - (l - len) / (vA[p].fi + vB[q].fi); --h; if(k <= vA[p].fi) { for(int64 i = k ; i <= vA[p].fi ; ++i) { putchar('A');++c; if(c == r - l + 1) return; } for(int64 i = 1 ; i <= vB[q].fi ; ++i) { putchar('B');++c; if(c == r - l + 1) return; } } else { k -= vA[p].fi; for(int64 i = k ; i <= vB[q].fi ; ++i) { putchar('B');++c; if(c == r - l + 1) return; } } while(h--) { for(int64 i = 1 ; i <= vA[p].fi ; ++i) { putchar('A');++c; if(c == r - l + 1) return; } for(int64 i = 1 ; i <= vB[q].fi ; ++i) { putchar('B');++c; if(c == r - l + 1) return; } } } len += t * (vA[p].fi + vB[q].fi); if(vA[p].se == 0) ++p; if(vB[q].se == 0) ++q; } } void Solve() { read(A);read(B);read(C);read(D); int64 L = 1,R = max(A,B); ML = (A + B); while(L < R) { int64 mid = (L + R) >> 1; if(check(A,B,mid) || check(B,A,mid)) R = mid; else L = mid + 1; } vA.clear();vB.clear(); if(A == ((B - 1) / L)) { int64 t = B / L; int64 rem = B - L * t; vA.pb(mp(0,1)); vA.pb(mp(1,A)); if(rem) vB.pb(mp(rem,1)); vB.pb(mp(L,t)); } else if(B == (A - 1) / L){ int64 t = A / L; int64 rem = A - t * L; vA.pb(mp(L,t)); if(rem) vA.pb(mp(rem,1)); vB.pb(mp(1,B));vB.pb(mp(0,1)); } else { int64 l = max((A - 1) / L + 1,(B - 1) / L + 1),r = min(A,B); while(l < r) { int64 m = (l + r + 1) >> 1; int64 ta = (A - m) / (L - 1); int64 tb = (B - m) / (L - 1); ta = ta * 2 + 1; tb = 2 * m - (tb * 2); if(ta + 1 < tb) r = m - 1; else l = m; } if(A > l) { int64 ka = (A - l - 1) / (L - 1); int64 rem = A - l - ka * (L - 1); vA.pb(mp(L,ka));vA.pb(mp(1 + rem,1));vA.pb(mp(1,l - ka - 1)); } else vA.pb(mp(1,l)); if(B > l) { int64 kb = (B - l - 1) / (L - 1); int64 rem = B - l - kb * (L - 1); vB.pb(mp(1,l - kb - 1));vB.pb(mp(1 + rem,1));vB.pb(mp(L,kb)); } else vB.pb(mp(1,l)); } Process(C,D); enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif int Q; read(Q); while(Q--) { Solve(); } }
這題很迷,複雜度很迷
記錄\(f(S)\)表示\(S\)字符串的答案
而後要麼第一個字符不要\(f(S) += (s[0] + 1)f(2...|S|)\)
要麼就是我枚舉一個長度,枚舉一個壓縮次數
每段都取一個按位且的值,而後計算這個字符串壓縮方案數,以後再加上後面的字符串壓縮方法
寫起來容易一點能夠寫成記搜,而後用map記錄每一個string的答案
跑了不到2s,複雜度超級迷
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define pdi pair<db,int> #define pll pair<int64,int64> #define mp make_pair #define pb push_back #define enter putchar('\n') #define space putchar(' ') #define eps 1e-8 #define mo 974711 #define MAXN 200005 //#define ivorysi 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 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; } void update(int &x,int y) { x = inc(x,y); } map<string,int> mm; string operator & (const string &a,const string &b) { int l = a.length(); string c(l,'0'); for(int i = 0 ; i < l ; ++i) { if(a[i] == '1' && b[i] == '1') c[i] = '1'; } return c; } int dfs(string s) { if(s.empty()) return 1; if(s.length() == 1) return s[0] == '0' ? 1 : 2; if(mm.count(s)) return mm[s]; int res = 0; res = mul(s[0] == '1' ? 2 : 1,dfs(s.substr(1))); int l = s.length(); for(int d = 1 ; d <= l ; ++d) { string t = s.substr(0,d); for(int k = d ; k <= l ; k += d) { if(k + d - 1 >= l) break; t = t & s.substr(k,d); update(res,mul(dfs(t),dfs(s.substr(k + d)))); } } mm[s] = res; return res; } void Solve() { string s; cin >> s; out(dfs(s));enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
把最長的一段挑出來,一個端點做爲0
而後把剩下\(N - 1\)放置的點的位置分紅整數部分和小數部分
咱們枚舉一個排列,是N - 1個點小數的排列順序,能夠認爲排列互不相同
而後能夠抽象出\(C * N\)個點,第\(i\)行第\(j\)列表示整數部分是\(i\)小數部分排行爲\(j\)
記錄一個dp[a][b][S]表示當前在\(a\)點,最遠能到b點,選了點狀態爲S
答案就是dp[C * N][C * N][2^{N - 1} - 1]
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define pdi pair<db,int> #define pll pair<int64,int64> #define mp make_pair #define pb push_back #define enter putchar('\n') #define space putchar(' ') #define eps 1e-8 #define mo 974711 #define MAXN 200005 //#define ivorysi 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); } int a[15],L[15],N,C; bool vis[15]; int64 f[2][305][(1 << 5) + 5]; db ans,pw; void Process() { memset(f,0,sizeof(f)); int cur = 0; f[cur][min(C * N,L[N] * N)][0] = 1; for(int i = 1 ; i < C * N ; ++i) { if(i % N == 0) continue; memset(f[cur ^ 1],0,sizeof(f[cur ^ 1])); int t = i % N - 1; for(int j = i ; j <= C * N ; ++j) { for(int k = 0 ; k < (1 << N - 1) ; ++k) { if(!f[cur][j][k]) continue; f[cur ^ 1][j][k] += f[cur][j][k]; if(k & (1 << t)) continue; f[cur ^ 1][min(C * N,max(j,i + L[a[t + 1]] * N))][k ^ (1 << t)] += f[cur][j][k]; } } cur ^= 1; } ans += f[cur][C * N][(1 << N - 1) - 1]; } void dfs(int dep) { if(dep >= N) { Process();return; } for(int i = 1 ; i < N ; ++i) { if(!vis[i]) { a[dep] = i; vis[i] = 1; dfs(dep + 1); vis[i] = 0; } } } void Solve() { read(N);read(C); for(int i = 1 ; i <= N ; ++i) read(L[i]); sort(L + 1,L + N + 1); pw = 1; for(int i = 1 ; i < N ; ++i) pw = pw * C; dfs(1); ans *= 1.0 / pw; pw = 1.0; for(int i = 2 ; i < N ; ++i) pw = pw * i; ans *= 1.0 / pw; printf("%.11lf\n",ans); } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }