用一個棧,若是遇到S就彈入,若是遇到T棧裏有S就彈出棧頂,不然T在最後的串裏,最後計算出的T和棧裏剩的S就是答案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 200005 //#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); } char s[MAXN]; int top,N; void Solve() { scanf("%s",s + 1); N = strlen(s + 1); int ans = 0; for(int i = 1 ; i <= N ; ++i) { if(s[i] == 'T') { if(top) --top; else ++ans; } else { ++top; } } ans += top; out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
就是單調棧求出左邊最靠近它且比它小的數,右邊最靠近且比它小的數,就能夠計算出以這個點爲最小值的區間有多少了ios
#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 200005 //#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],l[MAXN],r[MAXN]; int sta[MAXN],top; int64 ans = 0; void Solve() { read(N); for(int i = 1 ; i <= N ; ++i) read(a[i]); for(int i = 1 ; i <= N ; ++i) { while(top && a[sta[top]] > a[i]) --top; l[i] = sta[top] + 1; sta[++top] = i; } top = 0;sta[0] = N + 1; for(int i = N ; i >= 1 ; --i) { while(top && a[sta[top]] > a[i]) --top; r[i] = sta[top] - 1; sta[++top] = i; } for(int i = 1 ; i <= N ; ++i) { ans += 1LL * (i - l[i] + 1) * (r[i] - i + 1) * a[i]; } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
最大的A確定是直徑,若是直徑是奇數,看看最小值是否是兩個,其他的長度必須都大於等於2個c++
若是直徑是偶數,看看最小值是否是1個,其他的長度必須大於等於兩個數組
#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 200005 //#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 D,N,a[MAXN],cnt[MAXN]; void Solve() { read(N); for(int i = 1 ; i <= N ; ++i) {read(a[i]);cnt[a[i]]++;} for(int i = 1 ; i <= N ; ++i) D = max(D,a[i]); if(D & 1) { if(cnt[D / 2 + 1] != 2) {puts("Impossible");return;} int res = 0; for(int i = D / 2 + 1 ; i <= D ; ++i) { res += cnt[i]; if(cnt[i] < 2) {puts("Impossible");return;} } if(res != N) {puts("Impossible");return;} } else { if(cnt[D / 2] != 1) {puts("Impossible");return;} int res = 1; for(int i = D / 2 + 1 ; i <= D ; ++i) { res += cnt[i]; if(cnt[i] < 2) {puts("Impossible");return;} } if(res != N) {puts("Impossible");return;} } puts("Possible");return; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
用經典容斥,設\(g(i)\)爲至少i個位置不合法的狀況優化
答案就是\(\sum_{i = 0}^{n}(-1)^{i}g(i)\)spa
以\([1,2K - 1]\)開頭,每\(2K\)個選擇一個構成的這樣的序列,這個序列當前的數每一個能填什麼,之和上一個數選擇什麼有關,這個能夠用一個dp完成,而後能夠獲得每一個序列裏至少選了\(i\)個方案數rest
組合起來能夠用NTT優化code
#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 2005 //#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); } const int MOD = 924844033,g = 5,MAXL = (1 << 15); int N,K; int a[MAXN],W[MAXL + 5],f[2][MAXN][2],p[MAXL + 5]; int ans[MAXL + 5],fac[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; } void update(int &x,int y) { x = inc(x,y); } int fpow(int x,int c) { int res = 1,t = x; while(c) { if(c & 1) res = mul(res,t); t = mul(t,t); c >>= 1; } return res; } void NTT(int *p,int L,int on) { for(int i = 1 , j = L >> 1 ; i < L - 1 ; ++i) { if(i < j) swap(p[i],p[j]); int k = L >> 1; while(j >= k) { j -= k; k >>= 1; } j += k; } for(int h = 2 ; h <= L ; h <<= 1) { int wn = W[(MAXL + on * MAXL / h) % MAXL]; for(int k = 0 ; k < L ; k += h) { int w = 1; for(int j = k ; j < k + h / 2 ; ++j) { int u = p[j],t = mul(p[j + h / 2],w); p[j] = inc(u,t); p[j + h / 2] = inc(u,MOD - t); w = mul(w,wn); } } } if(on == -1) { int invL = fpow(L,MOD - 2); for(int i = 0 ; i < L ; ++i) p[i] = mul(p[i],invL); } } void Solve() { read(N);read(K); W[0] = 1;W[1] = fpow(g,(MOD - 1) / MAXL); for(int i = 2 ; i < MAXL ; ++i) W[i] = mul(W[i - 1],W[1]); int len = 1; while(len <= N) len <<= 1; ans[0] = 1; NTT(ans,len,1); for(int i = 1 ; i <= 2 * K ; ++i) { memset(f,0,sizeof(f)); int cur = 0; f[cur][0][0] = 1;int cnt = 0; for(int j = i ; j <= N ; j += 2 * K) { memset(f[cur ^ 1],0,sizeof(f[cur ^ 1])); for(int h = 0 ; h <= cnt ; ++h) { update(f[cur ^ 1][h][0],inc(f[cur][h][0],f[cur][h][1])); if(j - K >= 1) update(f[cur ^ 1][h + 1][0],f[cur][h][0]); if(j + K <= N) update(f[cur ^ 1][h + 1][1],inc(f[cur][h][0],f[cur][h][1])); } ++cnt; cur ^= 1; } memset(p,0,sizeof(p)); for(int j = 0 ; j <= N ; ++j) { p[j] = inc(f[cur][j][0],f[cur][j][1]); } NTT(p,len,1); for(int j = 0 ; j < len ; ++j) { ans[j] = mul(ans[j],p[j]); } } NTT(ans,len,-1); fac[0] = 1; for(int i = 1 ; i <= N ; ++i) fac[i] = mul(fac[i - 1],i); int res = 0; for(int i = 0 ; i <= N ; ++i) { if(i & 1) update(res,MOD - mul(fac[N - i],ans[i])); else update(res,mul(fac[N - i],ans[i])); } out(res);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
觀察出-1的條件是先手走到一條紅邊的某個端點,這個紅邊的兩個端點在藍邊樹上的距離大於等於3get
以後咱們能夠進行深搜,若是能夠到某個點,先手和這個點的距離小於後手到達這個的距離就能夠走,不然不行string
若是走到特殊點輸出-1,不然就是能走到的距離後手最遠的距離乘2
#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 200005 //#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); } vector<int> to[2][MAXN]; int fa[MAXN][20],dep[MAXN]; int N,X,Y,ans; bool flag = 0; int lca(int u,int v) { if(dep[u] < dep[v]) swap(u,v); int l = 18; while(dep[u] > dep[v]) { if(dep[fa[u][l]] >= dep[v]) { u = fa[u][l]; } --l; } if(u == v) return u; l = 18; while(fa[u][0] != fa[v][0]) { if(fa[u][l] != fa[v][l]) { u = fa[u][l]; v = fa[v][l]; } --l; } return fa[u][0]; } int dist(int u,int v) { return dep[u] + dep[v] - 2 * dep[lca(u,v)]; } void dfs(int u) { for(auto t : to[1][u]) { if(t != fa[u][0]) { dep[t] = dep[u] + 1; fa[t][0] = u; dfs(t); } } } void dfs1(int u,int f,int d) { if(u == Y) return; ans = max(ans,dep[u] - 1); for(auto t : to[0][u]) { if(t == f) continue; if(dist(u,t) > 2) flag = 1; if(d + 1 < dep[t] - 1) dfs1(t,u,d + 1); } } void Solve() { read(N);read(X);read(Y); int a,b; for(int i = 1 ; i < N ; ++i) { read(a);read(b); to[0][a].pb(b);to[0][b].pb(a); } for(int i = 1 ; i < N ; ++i) { read(a);read(b); to[1][a].pb(b);to[1][b].pb(a); } dep[Y] = 1; dfs(Y); for(int j = 1 ; j <= 19 ; ++j) { for(int i = 1 ; i <= N ; ++i) { fa[i][j] = fa[fa[i][j - 1]][j - 1]; } } dfs1(X,0,0); if(flag) {puts("-1");} else {out(2 * ans);enter;} } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
咱們把一個點的貢獻轉化爲一條邊的貢獻,由於邊的數量是點的數量-1,最後再加上選點方案數\(\binom{n}{k}\)便可
一條邊的貢獻是\(\binom{n}{k} - \binom{a}{k} - \binom{n - a}{k}\)就是在n個點裏選k個點,去掉不合法的狀況也就是k個點都在去掉這條邊的兩個子樹裏
而後咱們要統計的就是\(\binom{a}{k} + \binom{n - a}{k}\)
這個能夠轉化成\(ans_{k} = \sum_{i = 1}^{n} b_{i} \binom{i}{k}\)
\(ans_{k} = \frac{1}{k!} \sum_{i = 1}^{n} b_{i} i! \frac{1}{(i - k)!}\)
這個數組是能夠卷積的,只要把一個倒過來就行
設\(f(i) = \frac{1}{(n - i)!}\)
\(g(i) = b_{i}i!\)
\(h = g * f\)
\(ans_{k} = h(N + k)\)
#include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <cmath> #include <cstring> #include <map> //#define ivorysi #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define mp make_pair #define pb push_back #define fi first #define se second #define mo 974711 #define RG register #define MAXN 200005 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) {putchar('-');x = -x;} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } struct node { int to,next; }E[MAXN * 2]; int head[MAXN],sumE; void add(int u,int v) { E[++sumE].to = v; E[sumE].next = head[u]; head[u] = sumE; } const int MOD = 924844033,L = (1 << 19),G = 5; int N,f[L + 5],fac[MAXN],invfac[MAXN],b[L + 5],W[L + 5]; int mul(int a,int b) {return 1LL * a * b % MOD;} int inc(int a,int b) {a = a + b;if(a >= MOD) a -= MOD;return a;} int fpow(int x,int c) { int t = x,res = 1; while(c) { if(c & 1) res = mul(res,t); t = mul(t,t); c >>= 1; } return res; } int C(int n,int m) { if(n < m) return 0; return mul(mul(fac[n],invfac[m]),invfac[n - m]); } int dfs(int u,int fa) { int siz = 1; for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(v != fa) { siz += dfs(v,u); } } if(fa != 0) { b[siz]++; b[N - siz]++; } return siz; } void NTT(int *a,int LEN,int on) { for(int i = 1 , j = LEN / 2 ; i < LEN - 1 ; ++i) { if(i < j) swap(a[i],a[j]); int k = LEN / 2; while(j >= k) { j -= k; k >>= 1; } j += k; } for(int h = 2 ; h <= LEN ; h <<= 1) { int wn = W[(L + on * L / h) % L]; for(int k = 0 ; k < LEN ; k += h) { int w = 1; for(int j = k ; j < k + h / 2 ; ++j) { int64 u = a[j],t = 1LL * a[j + h / 2] * w; a[j] = (u + t) % MOD; a[j + h / 2] = (u - t + 1LL * MOD * MOD) % MOD; w = mul(w,wn); } } } if(on == -1) { int invL = fpow(LEN,MOD - 2); for(int i = 0 ; i < LEN ; ++i) a[i] = mul(a[i],invL); } } void Solve() { read(N); int u,v; for(int i = 1 ; i < N ; ++i) { read(u);read(v);add(u,v);add(v,u); } dfs(1,0); fac[0] = 1; for(int i = 1 ; i <= N ; ++i) fac[i] = mul(fac[i - 1],i); invfac[N] = fpow(fac[N],MOD - 2); for(int i = N - 1 ; i >= 0 ; --i) invfac[i] = mul(invfac[i + 1],i + 1); for(int i = 0 ; i <= N ; ++i) f[N - i] = invfac[i]; for(int i = 1 ; i <= N ; ++i) b[i] = mul(b[i],fac[i]); W[0] = 1;W[1] = fpow(G,(MOD - 1) / L); for(int i = 2 ; i < L ; ++i) W[i] = mul(W[i - 1],W[1]); int t = 1; while(t <= 2 * N) t <<= 1; NTT(b,t,1);NTT(f,t,1); for(int i = 0 ; i < t ; ++i) f[i] = mul(f[i],b[i]); NTT(f,t,-1); for(int i = 1 ; i <= N ; ++i) { int ans = mul(f[i + N],invfac[i]); ans = inc(mul(N,C(N,i)),MOD - ans); out(ans);enter; } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }