把每一個B後面的W個數累加起來便可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 1000005 //#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); } char s[200005]; int64 ans = 0; int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif scanf("%s",s + 1); int64 t = 0; int N = strlen(s + 1); for(int i = N ; i >= 1 ; --i) { if(s[i] == 'W') ++t; else ans += t; } out(ans);enter; }
這比賽打的太難受了c++
這個我花了一個樹結構,蒙了一個dp,而後wa了,去硬上T2網絡
最後發現我把一個N改爲離散化後的tot就A了spa
就是考慮一個點,和它組成剛好大於它的\(2^{i}\)的值只有一個,構成了一片森林,對於每一個森林從底向上更新,若是父親和兒子能配對就儘量多的配對code
每一個\(2^{i}\)的點如有剩餘再兩兩配對遊戲
#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); } struct node { int to,next; }E[MAXN * 10]; map<int,int> mm; int val[MAXN],A[MAXN],N,tot,ans; int head[MAXN],sumE,dp[MAXN]; bool vis[MAXN]; int lowbit(int x) { return x & (-x); } void add(int u,int v) { E[++sumE].to = v; E[sumE].next = head[u]; head[u] = sumE; } void Init() { read(N); for(int i = 1 ; i <= N ; ++i) { read(A[i]); val[i] = A[i]; mm[A[i]]++; } sort(val + 1,val + N + 1); tot = unique(val + 1,val + N + 1) - val - 1; for(int i = 1 ; i <= N ; ++i) { int a = val[i]; int k = lower_bound(val + 1,val + tot + 1,a) - val; for(int64 t = 1 ; t <= 1073741824 ; t <<= 1) { if(t > 2 * a) { if(mm[t - a] == 0) continue; int h = lower_bound(val + 1,val + tot + 1,t - a) - val; add(k,h); } } } } void dfs(int u) { vis[u] = 1; dp[u] = mm[val[u]]; for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(!vis[v]) { dfs(v); int t = min(dp[u],dp[v]); dp[u] -= t; dp[v] -= t; ans += t; } } } void Solve() { for(int i = 1 ; i <= tot ; ++i) { if(!vis[i]) dfs(i); if(lowbit(val[i]) == val[i]) ans += dp[i] / 2; } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Init(); Solve(); }
好不容易想到了一個分段維護一個字符個數進制下的數get
沒想到二分,gg了it
#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; int A[MAXN]; int pw[MAXN][25],cnt[MAXN],ans; vector<pii > v; void Init() { read(N); for(int i = 1 ; i <= N ; ++i) read(A[i]); cnt[1] = 1000000000; for(int i = 1 ; i <= N ; ++i) { pw[i][0] = 1; for(int j = 1 ; j <= 20 ; ++j) { if(pw[i][j - 1] > N / i) { cnt[i] = j - 1;break; } pw[i][j] = pw[i][j - 1] * i; } } } bool check(int mid) { v.clear(); v.pb(mp(A[1],0));int sum = A[1]; for(int i = 2 ; i <= N ; ++i) { if(A[i] <= A[i - 1]) { if(mid == 1) return false; if(sum < A[i - 1]) {v.pb(mp(A[i - 1] - sum,0));sum = A[i - 1];} int s = v.size() - 1; for(int k = s ; k >= 0 ; --k) { if(sum - v[k].fi >= A[i]) {sum -= v[k].fi;v.pop_back();} else { int t = sum - A[i]; if(t > cnt[mid]) v[k].se = 0; else v[k].se /= pw[mid][t]; v[k].fi -= t; sum = A[i]; } if(sum == A[i]) break; } s = v.size() - 1; for(int k = s ; k >= 0 ; --k) { if(v[k].fi <= cnt[mid]) { if(v[k].se + 1 < pw[mid][v[k].fi]) {++v[k].se;break;} else { v[k].se = 0;if(k == 0) return false; } } else {++v[k].se;break;} } } } return true; } void Solve() { int l = 1,r = N; 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 Init(); Solve(); }
這題好水啊= =開D我就win了啊,sdC一直不過太難受了啊io
就是考慮咱們確定是走到某個障礙物上面,遊戲結束了class
如何判斷能不能走到呢,首先若是這一列是\(j\),咱們所在的行\(i\)必須大於等於\(j\),若是有一個連成一串的障礙物從\((j,j)\)開始往下壓
每次最多壓了多少,就是當前列最靠下不能走的點\(h\),求一個\(t = h - i + 1\)
\(t\)每次取一個前綴\(max\),而後對於每一列把行大於等於\(j + t\)的障礙物都設成不合法便可
把每一列能走到最靠上的障礙物取一個\(min\)
#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 H,W,N; vector<int> v[MAXN]; bool pass[MAXN]; void Solve() { read(H);read(W);read(N); int x,y; for(int i = 1 ; i <= N ; ++i) { read(x);read(y); v[y].pb(x); } for(int i = 1 ; i <= W ; ++i) v[i].pb(H + 1); sort(v[1].begin(),v[1].end()); int ans = v[1][0] - 1; int t = 0; for(int i = 2 ; i <= W ; ++i) { sort(v[i].begin(),v[i].end()); int s = v[i].size(); int m = 0; for(int k = 0 ; k < s ; ++k) { if(v[i][k] <= i + t) {pass[v[i][k]] = 1;m = max(v[i][k],m);} else if(pass[v[i][k] - 1]) {pass[v[i][k]] = 1;m = max(v[i][k],m);} else { ans = min(ans,v[i][k] - 1); break; } } t = max(t,m - i + 1); } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
關注一下一個路徑的根綴最大值
把根綴最大值相同的部分挑出來
咱們發現一個根綴最大值是\(u\),\(u\)的某個兒子是\(v\),\(v\)中的全部節點要走到\(u\),就要通過\(v\)中全部根綴最大值爲\(u\)的部分,這個能夠差分實現
而根綴最大值自身討論起來有點麻煩,直接搜索便可
#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; struct node { int to,next; }E[MAXN * 2]; int head[MAXN],sumE; int mv[MAXN],siz[MAXN],d[MAXN],c[MAXN],son[MAXN]; void add(int u,int v) { E[++sumE].next = head[u]; E[sumE].to = v; head[u] = sumE; } void calc(int u,int fa,int val) { son[u] = 1; for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(v != fa && v < val) { calc(v,u,val); son[u] += son[v]; } } } void dfs(int u,int fa) { mv[u] = max(mv[fa],u); 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]; d[u] += d[v]; } } if(mv[u] == u) { calc(u,fa,mv[fa]); d[u] = -siz[u]; } if(mv[fa] == fa) d[u] += siz[u]; } void dfs2(int u,int fa) { if(fa) { if(mv[u] == u) {c[u] += son[u];} else if(mv[fa] == fa) {c[u] -= son[u];c[u] += d[u];} c[u] += c[fa]; } for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(v != fa) { dfs2(v,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); } } void Solve() { dfs(1,0); dfs2(1,0); for(int i = 2 ; i <= N ; ++i) { out(c[i]); i == N ? enter : space; } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Init(); Solve(); }
\(2 \cdot 10^{5}\)的網絡流,有毒,不會卡常,棄療了,再見