若是符号相同,那么若是y比x大直接走,不然须要两次反号node
若是符号不一样,须要绝对值的差加一次反号c++
若是有一个是0,且y比x要小,那只须要一次反号spa
#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 5005 //#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); } int64 x,y; void Solve() { read(x);read(y); if(x * y >= 0) { if(y >= x) {out(y - x);enter;} else if(x * y != 0) {out(x - y + 2);enter;} else {out(x - y + 1);enter;} } else { out(abs(abs(x) - abs(y)) + 1);enter; } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
合法的序列中必须有一段长度大于等于K的同色的段便可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 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,K; int64 pre[MAXN],suf[MAXN],a[MAXN],sum[MAXN]; void Solve() { read(N);read(K); for(int i = 1 ; i <= N ; ++i) { read(a[i]); sum[i] = sum[i - 1] + a[i]; pre[i] = pre[i - 1]; if(a[i] > 0) pre[i] = pre[i] + a[i]; } for(int i = N ; i >= 1 ; --i) { suf[i] = suf[i + 1]; if(a[i] > 0) suf[i] = suf[i] + a[i]; } int64 ans = 0; for(int i = 1 ; i <= N ; ++i) { int r = i + K - 1; if(r > N) break; int64 all = pre[i - 1] + suf[r + 1]; if(sum[r] - sum[i - 1] > 0) all += sum[r] - sum[i - 1]; ans = max(ans,all); } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
简单分析一下只有I,O,L,J是有用的rem
咱们先尽可能一个I,一个L,一个J拼成一个长度为6的get
而后剩下的II两两组合,L两两组合,J两两组合it
若是I,J,L剩下的有两个,且我拼过一个长度为6的,那么我把这个长度为6的拆开分给这两个class
#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); } int64 aI,aO,aT,aJ,aL,aS,aZ; int64 ans = 0; void Solve() { read(aI);read(aO);read(aT);read(aJ);read(aL);read(aS);read(aZ); ans = aO; int64 t = min(aI,min(aJ,aL)); ans += 3 * t; aI -= t;aJ -= t;aL -= t; ans += (aI / 2) * 2;aI %= 2; ans += (aJ / 2) * 2;aJ %= 2; ans += (aL / 2) * 2;aL %= 2; if(aI + aJ + aL >= 2) { if(t) { ans -= 3;ans += 4; } } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
直接把这些位置排序,而后按照须要给位置最前且没有知足的位置填须要的数date
而后若是一个位置过去了,咱们把它后面的数,例如第2个2填完了,咱们把N - 2个2扔进一个vector,vector里面的数不在意顺序,随取随用
若是没有数用了也是不合法
#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 505 //#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; int x[MAXN],id[MAXN]; int val[MAXN * MAXN]; bool vis[MAXN]; vector<int> r; void Solve() { read(N); for(int i = 1 ; i <= N ; ++i) { read(x[i]); val[x[i]] = i; id[i] = i; } sort(id + 1,id + N + 1,[](int a,int b){return x[a] < x[b];}); int p = 1,rem = id[1] - 1; vis[1] = 1; for(int i = 1 ; i <= N * N ; ++i) { if(val[i]) { if(!vis[val[i]]) {puts("No");return;} for(int j = 1 ; j <= N - val[i] ; ++j) r.pb(val[i]); } else { while(!rem && p < N) {++p;rem = id[p] - 1;} if(rem) { val[i] = id[p]; --rem; if(!rem) vis[id[p]] = 1; } else { if(r.size() == 0) {puts("No");return;} val[i] = r.back();r.pop_back(); } } } puts("Yes"); for(int i = 1 ; i <= N * N ; ++i) {out(val[i]);space;} enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
咱们直接建一张i->a[i]的图,最后咱们用排列i->p[i]建出的图至关于一次走一步或者一次走两步
发现这是分开的不少基环内向树,咱们分开算答案统计便可
若是有一个环,环上的某些点挂着链,链必须只是单链,不然就不合法
至关于往环上放点,若是一个点上挂着链,那么这个点以前链长的边都会被这个点占据
咱们把占据的都标记好了,发现这些占据不重合的时候才算合法
这个时候咱们看看这个点链长+1前位置的边是否被占据,若是没有被占据,这个点挂着的链在环上就有两种填法
若是只有一个环,没有链
那么奇数的环(1除外)能够有两种走法
并且两个数量相同的环能够拼成一个新环,这个环上每一个人到目标位置距离都是2
能够用一个dp来计算相同点数的环的分配方案
把这些方案都乘起来就是总方案
#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); } const int MOD = 1000000007; int N,head[MAXN],sumE; int a[MAXN]; int deg[MAXN],line[MAXN]; bool vis[MAXN],mark[MAXN]; int cnt[MAXN],dp[MAXN],f[MAXN]; vector<int> v; 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); } queue<int> Q; void Solve() { read(N); for(int i = 1 ; i <= N ; ++i) { read(a[i]); ++deg[a[i]]; } for(int i = 1 ; i <= N ; ++i) { if(!deg[i]) Q.push(i); } while(!Q.empty()) { int u = Q.front();Q.pop(); vis[u] = 1; if(line[a[u]]) {puts("0");return;} line[a[u]] = line[u] + 1; if(!(--deg[a[u]])) Q.push(a[u]); } int ans = 1; for(int i = 1 ; i <= N ; ++i) { if(!vis[i]) { v.clear(); int p = i;v.pb(i);vis[p] = 1;p = a[p]; while(p != i) { vis[p] = 1; v.pb(p); p = a[p]; } int n = v.size(); bool no = 1; for(int j = 0 ; j < n ; ++j) { mark[j] = 0; if(line[v[j]]) no = 0; } if(no) {cnt[n]++;continue;} for(int j = 0 ; j < n ; ++j) { for(int k = 0 ; k < line[v[j]] ; ++k) { int t = ((j - k) % n + n) % n; if(mark[t]) {puts("0");return;} mark[t] = 1; } } for(int j = 0 ; j < n ; ++j) { if(!line[v[j]]) continue; int t = ((j - line[v[j]]) % n + n) % n; if(!mark[t]) ans = mul(ans,2); } } } for(int i = 1 ; i <= N ; ++i) { if(cnt[i]) { for(int j = 1 ; j <= cnt[i] ; ++j) dp[j] = 0; dp[0] = 1; for(int j = 1 ; j <= cnt[i] ; ++j) { dp[j] = dp[j - 1]; if((i & 1) && i != 1) update(dp[j],dp[j - 1]); if(j >= 2) { update(dp[j],mul(j - 1,mul(i,dp[j - 2]))); } } ans = mul(ans,dp[cnt[i]]); } } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
1300分的话,若是\(f(x,d)\)即从x点延伸d长度不为全集,那么若是d能够更小,咱们就不统计,也就是附近有个点\(f(y,d - 1)\)和它覆盖的是同样的
这个能够用x当根每一个儿子最大深度统计出来,就是两次树dp
把这个最大的d记作\(high[x]\)
而后咱们对于每一个点记录一个\(low[x]\)表示最小能从哪一个点往上延伸
咱们在求high的时候会发现每一个点和它当根的时候深度最大的那个儿子可能有一个low上的转移关系,咱们记录下来
而后咱们high从小到大枚举每一个点,若是这个点是偏心点,那么low是0,若是这个点low <= high,就证实这个点大于low的时候已是偏心点同样了,能够更新周围的点,利用咱们求的转移关系而后更新周围点便可
#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); } struct node { int to,next; }E[MAXN * 2]; int N,head[MAXN],sumE,dep[MAXN],fr[MAXN],high[MAXN],low[MAXN]; char s[MAXN]; vector<int> rec[MAXN]; vector<pii > to[MAXN]; void add(int u,int v) { E[++sumE].to = v; E[sumE].next = head[u]; head[u] = sumE; } void dfs1(int u,int fa) { for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(v != fa) { dfs1(v,u); dep[u] = max(dep[u],dep[v] + 1); } } } void dfs2(int u,int fa) { vector<pii > vec; dep[u] = max(dep[u],fr[u] + 1); vec.pb(mp(1,u)); if(fa) vec.pb(mp(fr[u] + 2,fa)); pii p = mp(0,0); for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(v != fa) { vec.pb(mp(dep[v] + 2,v)); if(dep[v] > dep[p.se]) p.se = v; if(dep[p.se] > dep[p.fi]) swap(p.fi,p.se); } } sort(vec.begin(),vec.end()); high[u] = dep[u] - 1; int s = vec.size() - 1; high[u] = min(high[u],vec[s - 1].fi); if(high[u] < dep[u] - 1){ to[u].pb(mp(vec[s].se,high[u])); } vec.clear(); for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(v != fa) { fr[v] = max(fr[v],fr[u] + 1); if(v != p.fi) fr[v] = max(fr[v],dep[p.fi] + 1); if(v != p.se) fr[v] = max(fr[v],dep[p.se] + 1); } } for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(v != fa) { dfs2(v,u); } } } void Solve() { read(N); int a,b; for(int i = 1 ; i < N ; ++i) { read(a);read(b);add(a,b);add(b,a); } scanf("%s",s + 1); dep[0] = -1;fr[1] = -1; dfs1(1,0);dfs2(1,0); for(int i = 1 ; i <= N ; ++i) { rec[high[i]].pb(i); low[i] = high[i] + 1; } for(int i = 0 ; i <= N ; ++i) { for(auto v : rec[i]) { if(s[v] == '1') { low[v] = 0; } if(low[v] <= high[v]){ for(auto k : to[v]) { low[k.fi] = min(low[k.fi],k.se); } } } } int64 ans = 1; for(int i = 1 ; i <= N ; ++i) { ans += high[i] - low[i] + 1; } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0;