用個map愉悅一下就行了node
#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 N; int a[MAXN],ans; map<int,int> zz; void Init() { read(N); for(int i = 1 ; i <= N ; ++i) {read(a[i]);zz[a[i]] += 1;} sort(a + 1,a + N + 1); N = unique(a + 1,a + N + 1) - a - 1; } void Solve() { for(int i = 1 ; i <= N ; ++i) { if(zz[a[i]] < a[i]) ans += zz[a[i]]; else ans += zz[a[i]] - a[i]; } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Init(); Solve(); }
若是通過了奇數個T,那麼原來在x軸上走,後來確定在y軸上走,原來y軸變爲x軸
若是偶數個T,那麼保持原來的軸不變
咱們會選定一個方向使得在這個方向上走後面的F的個數
這個能夠用一個簡單的揹包(加上bitset優化一下)實現,注意在序列最前的F手動走完,由於沒法改爲X軸負方向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 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 N,x,y,s,t; char str[8005]; vector<int> dir[2]; bitset<16005> f[2]; bool cmp(int a,int b) { return a > b; } void Solve() { scanf("%s",str + 1);read(x);read(y); N = strlen(str + 1); int d = 0; s = 0,t = 0; int p = 1; while(p <= N && str[p] == 'F') {++s;++p;} int cnt = 0; for(int i = p ; i <= N ; ++i) { if(str[i] == 'T') { if(cnt) dir[d].pb(cnt); d ^= 1;cnt = 0; } else {++cnt;} } if(cnt) dir[d].pb(cnt); if(abs(s - x) > N) {puts("No");return;} int cur = 0; f[cur].reset(); f[cur][8000] = 1; for(auto k : dir[0]) { f[cur ^ 1].reset(); f[cur ^ 1] = (f[cur] << k) | (f[cur] >> k); cur ^= 1; } if(!f[cur][8000 + abs(s - x)]) {puts("No");return;} cur = 0; f[cur].reset(); f[cur][8000] = 1; for(auto k : dir[1]) { f[cur ^ 1].reset(); f[cur ^ 1] = (f[cur] << k) | (f[cur] >> k); cur ^= 1; } if(!f[cur][8000 + abs(t - y)]) {puts("No");return;} puts("Yes"); } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
給每一個能夠走的點的sg函數簡單推一下,從第(L - 1)層開始概括
很容易發現sg函數是lowbit(L - dep)函數
#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 son[MAXN][2],N,rt = 1,Ncnt = 1; int64 L,dep[MAXN]; char s[MAXN]; int64 lowbit(int64 x) { return x & -x; } void Insert(char *str) { int len = strlen(str + 1); int p = rt; for(int i = 1 ; i <= len ; ++i) { if(!son[p][str[i] - '0']) { son[p][str[i] - '0'] = ++Ncnt; dep[Ncnt] = dep[p] + 1; } p = son[p][str[i] - '0']; } } void Solve() { read(N);read(L); for(int i = 1 ; i <= N ; ++i) { scanf("%s",s + 1); Insert(s); } int64 ans = 0; for(int i = 1 ; i <= Ncnt ; ++i) { if((son[i][0] == 0 && son[i][1] != 0) || (son[i][0] != 0 && son[i][1] == 0)) { ans ^= lowbit(L - dep[i]); } } if(ans) puts("Alice"); else puts("Bob"); } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
第一個結論就推不出來QAQ
就是考慮一條邊,邊斷掉分紅兩個子樹是\(x,y\),這條邊最多被通過\(2min{siz[x],siz[y]}\)優化
考慮有兩個重心(也就是斷開一條邊能夠分紅兩個大小爲\(N / 2\)的子樹)
確定能夠構造合法的解,方案數就是\((\frac{N}{2}!)^2\)ui
有一個重心也是有解的,就是把全部的兒子從大到小排序
把最大的放在第一個,而後把剩下從小到大放,重心到它本身便可
這是一個合法解
那麼咱們能夠知道,知足條件的答案必定是重心隨便放,斷掉重心後,剩下的點必須不選本身所在的樹裏的點spa
咱們能夠容斥作,用\(f[k]\)選了k個點,且這k個點能到達的點都是本身子樹中的點,相似樹揹包那樣轉移
答案就是\(\sum_{i = 0}^{N - 1} (-1)^{i}f[i] \cdot (N - i)!\)code
#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 5005 //#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 = 1000000007; int N; struct node { int to,next; }E[MAXN * 2]; int head[MAXN],sumE,siz[MAXN],son[MAXN]; int C[MAXN][MAXN],fac[MAXN],val[MAXN],tot,f[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 add(int u,int v) { E[++sumE].next = head[u]; E[sumE].to = v; head[u] = sumE; } void dfs(int u,int fa) { siz[u] = 1; for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(v != fa) { dfs(v,u); siz[u] += siz[v]; son[u] = max(son[u],siz[v]); } } son[u] = max(son[u],N - siz[u]); } void Init() { read(N); int x,y; for(int i = 1 ; i < N ; ++i) { read(x);read(y); add(x,y);add(y,x); } C[0][0] = 1; for(int i = 1 ; i <= N ; ++i) { C[i][0] = 1; for(int j = 1 ; j <= N ; ++j) { C[i][j] = inc(C[i - 1][j],C[i - 1][j - 1]); } } fac[0] = 1; for(int i = 1 ; i <= N ; ++i) fac[i] = mul(fac[i - 1],i); } void Solve() { dfs(1,0); int g = 1; for(int i = 2 ; i <= N ; ++i) { if(son[i] < son[g]) g = i; } if(N % 2 == 0 && son[g] == N / 2) { out(mul(fac[N / 2],fac[N / 2]));enter;return; } for(int i = head[g] ; i ; i = E[i].next) { int v = E[i].to; if(siz[v] < siz[g]) val[++tot] = siz[v]; } if(g != 1) val[++tot] = N - siz[g]; int s = 0;f[0] = 1; for(int i = 1 ; i <= tot ; ++i) { for(int t = s + val[i] ; t >= 0 ; --t) { for(int j = 1 ; j <= val[i] ; ++j) { if(j > t) break; f[t] = inc(f[t],mul(mul(f[t - j],C[val[i]][j]),mul(C[val[i]][j],fac[j]))); } } s += val[i]; } int t = 1,ans = 0; for(int i = 0 ; i <= N - 1; ++i) { ans = inc(ans,mul(mul(t,f[i]),fac[N - i])); t = mul(t,MOD - 1); } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Init(); Solve(); }