不一樣的顏色段數-1node
#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 100005 //#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; char s[MAXN]; void Solve() { scanf("%s",s + 1); N = strlen(s + 1); int cnt = 0; for(int i = 2 ; i <= N ; ++i) { if(s[i] != s[i - 1]) ++cnt; } out(cnt);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
利潤最大是從某個位置以後的最大值減去該位置的值,由於a兩兩不一樣,因此假如從位置x買入,從某個y所有賣出能夠獲得最大利潤,那麼y最多隻有一個c++
統計有幾個x會有這樣的y,而後這就是咱們須要至少下降一個的位置ui
#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 100005 //#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,T; int a[MAXN]; set<int> S; void Solve() { read(N);read(T); for(int i = 1 ; i <= N ; ++i) read(a[i]); int D = 0; for(int i = N ; i >= 1 ; --i) { if(S.size()) { auto t = *(--S.end()); D = max(t - a[i],D); } S.insert(a[i]); } S.clear(); int ans = 0; for(int i = N ; i >= 1 ; --i) { if(S.size()) { if(S.find(a[i] + D) != S.end()) ++ans; } S.insert(a[i]); } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
咱們把一個固定數值的點做爲根,而後默認每次走一條邊都+1spa
咱們遇到已經固定值的點,可能須要把一些邊從+1改爲-1,因此算出來的值必須和固定值得差值是偶數code
咱們算出每一個固定數值的點上面須要有多少改爲-1的邊,記錄一個子樹最大值排序
從新從根遍歷整棵樹,若是子樹中最大值仍然大於1,就把連向這個兒子的邊改成-1,遍歷到一個點時看看當前是否合法,不合法就是-1get
#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 100005 //#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); } struct node { int to,next; }E[MAXN * 2]; int N,head[MAXN],sumE,K,val[MAXN],c[MAXN],dp[MAXN],mv[MAXN]; bool vis[MAXN]; bool flag = 0; void add(int u,int v) { E[++sumE].to = v; E[sumE].next = head[u]; head[u] = sumE; } void dfs(int u,int fa) { mv[u] = 1e9; if(vis[u]) { if(val[u] > c[u] || ((c[u] - val[u]) & 1)) {flag = 1;} else dp[u] = (c[u] - val[u]) / 2; mv[u] = dp[u]; } for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(v != fa) { c[v] = c[u] + 1; dfs(v,u); mv[u] = min(mv[u],mv[v]); } } } bool dfs2(int u,int fa,int d) { c[u] -= d * 2; if(vis[u] && c[u] != val[u]) return false; for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(v != fa) { int t = d; if(mv[v] - d > 0) ++t; if(!dfs2(v,u,t)) return false; } } return true; } void Solve() { read(N); int a,b; for(int i = 1 ; i < N ; ++i) { read(a);read(b); add(a,b);add(b,a); } read(K); int v,p; for(int i = 1 ; i <= K ; ++i) { read(v);read(p); vis[v] = 1;val[v] = p; } int rt; for(int i = 1 ; i <= N ; ++i) { if(vis[i]) {rt = i;break;} } c[rt] = val[rt]; dfs(rt,0); if(flag) {puts("No");return;} if(!dfs2(rt,0,0)) {puts("No");return;} puts("Yes"); for(int i = 1 ; i <= N ; ++i) {out(c[i]);enter;} } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
這個須要注意到一個性質,答案的下界是\(2max(H,W) + 1\)it
這告訴咱們什麼,這個空白矩形最優答案必定過\(y = H / 2\)或\(x = W / 2\)class
咱們就能夠對x進行排序,從前日後遍歷,存兩個單調棧,一個棧底到棧頂遞增,y值都小於H/2,一個棧底到棧頂遞減,y值都大於H / 2date
對於一個i,咱們要存的是當前棧裏在i+1及之後最大的\(y_1\)小於H / 2,\(y_2\)大於H/2,存一個\(y_2 - y_1\)
咱們要找的就是\((y _2 - y_1) - x_{i}\)最大的那個i,而後加上當前遍歷到的\(x\),就是以x爲右邊界可能被計入答案的最大的矩形
#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 300005 //#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); } struct node { int l,r,ad,v; }tr[MAXN * 4]; int W,H,N,ans; pii p[MAXN]; int sta[2][MAXN],top[2]; void update(int u) { tr[u].v = max(tr[u << 1].v,tr[u << 1 | 1].v); } void addlz(int u,int v) { tr[u].ad += v;tr[u].v += v; } void pushdown(int u) { if(tr[u].ad) { addlz(u << 1,tr[u].ad); addlz(u << 1 | 1,tr[u].ad); tr[u].ad = 0; } } void build(int u,int l,int r) { tr[u].l = l;tr[u].r = r;tr[u].ad = 0; if(l == r) { tr[u].v = H - p[l].fi;return; } int mid = (l + r) >> 1; build(u << 1,l,mid); build(u << 1 | 1,mid + 1,r); update(u); } void add(int u,int l,int r,int v) { if(l > r || !v) return; if(tr[u].l == l && tr[u].r == r) { addlz(u,v);return; } pushdown(u); int mid = (tr[u].l + tr[u].r) >> 1; if(r <= mid) add(u << 1,l,r,v); else if(l > mid) add(u << 1 | 1,l,r,v); else {add(u << 1,l,mid,v);add(u << 1 | 1,mid + 1,r,v);} update(u); } int query(int u,int l,int r) { if(l > r) return 0; if(tr[u].l == l && tr[u].r == r) return tr[u].v; pushdown(u); int mid = (tr[u].l + tr[u].r) >> 1; if(r <= mid) return query(u << 1,l,r); else if(l > mid) return query(u << 1 | 1,l,r); else return max(query(u << 1,l,mid),query(u << 1 | 1,mid + 1,r)); } int Calc() { sort(p + 1,p + N + 1); build(1,0,N); top[0] = top[1] = 0; memset(sta,0,sizeof(sta)); int res = 0; for(int i = 1 ; i <= N ; ++i) { res = max(res,query(1,0,i - 1) + p[i].fi); if(p[i].se > H / 2) { int pre = H,pos = i; while(top[1] && p[sta[1][top[1]]].se > p[i].se) { add(1,sta[1][top[1]],pos - 1,-pre); pre = p[sta[1][top[1]]].se; pos = sta[1][top[1]]; --top[1]; } add(1,sta[1][top[1]],pos - 1,-pre); add(1,sta[1][top[1]],i - 1,p[i].se); sta[1][++top[1]] = i; } else { int pre = 0,pos = i; while(top[0] && p[sta[0][top[0]]].se < p[i].se) { add(1,sta[0][top[0]],pos - 1,pre); pre = p[sta[0][top[0]]].se; pos = sta[0][top[0]]; --top[0]; } add(1,sta[0][top[0]],pos - 1,pre); add(1,sta[0][top[0]],i - 1,-p[i].se); sta[0][++top[0]] = i; } } res = max(res,query(1,0,N) + W); return 2 * res; } void Solve() { read(W);read(H);read(N); for(int i = 1 ; i <= N ; ++i) { read(p[i].fi);read(p[i].se); } ans = 2 * max(H,W) + 1; ans = max(ans,Calc()); for(int i = 1 ; i <= N ; ++i) swap(p[i].fi,p[i].se); swap(W,H); ans = max(ans,Calc()); out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }