若是每一個數都是一個一個間隔開的,那麼答案是\(n!\)node
考慮把一個數挪到1,第二個數挪到3,以此類推,若是不行,證實前面中有個數確定會被選擇,因此任意選一個數到終點,繼續這樣的操做c++
最後剩下的乘一個階乘便可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 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,ans; int x[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); } void Solve() { read(N); for(int i = 1 ; i <= N ; ++i) read(x[i]); int pre = 0; int cnt = 0,ans = 1; for(int i = 1 ; i <= N ; ++i) { if(x[i] > pre) {++cnt;pre += 2;} else ans = mul(ans,cnt + 1); } for(int i = 1 ; i <= cnt ; ++i) ans = mul(ans,i); out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
顯然咱們必須先恢復出一行來,而後去更新一開始沒有全滿的列code
要麼是第j列有黑格子,咱們用它去恢復出第j行,要麼給第j列創造一個黑格子,恢復出第j行ci
#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[505][505]; int sumr[505],sumc[505]; bool vis[505]; void Solve() { read(N); bool flag = 0; for(int i = 1 ; i <= N ; ++i) { scanf("%s",s[i] + 1); for(int j = 1 ; j <= N ; ++j) { if(s[i][j] == '#') flag = 1; } } if(!flag) { puts("-1");return; } for(int i = 1 ; i <= N ; ++i) { for(int j = 1 ; j <= N ; ++j) { if(s[i][j] == '#') vis[j] = 1; } } int cnt = 0; for(int j = 1 ; j <= N ; ++j) { int c = 0; for(int i = 1 ; i <= N ; ++i) { c += (s[i][j] == '#'); } if(c == N) ++cnt; } int ans = 2 * N; for(int i = 1 ; i <= N ; ++i) { int c = 0; for(int j = 1 ; j <= N ; ++j) { c += (s[i][j] == '.'); } ans = min(ans,c + N - cnt + (vis[i] ^ 1)); } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
用處理出\(nxt(l)\)表示l以後到第幾個位置能變成空get
同時記錄\(nxt_{a}(l),nxt_{b}(l)\)一直到z,初始時候先把s[l + 1]的數設成l + 1,而後從這個位置開始循環更新string
而後咱們一次詢問就是不斷的\(nxt(l - 1)\)嵌套,咱們處理出2的次冪次操做便可it
#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 500005 //#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]; int nxt[MAXN][27],ri[MAXN][27]; void Solve() { scanf("%s",s + 1); N = strlen(s + 1); for(int i = 0 ; i <= N + 1; ++i) { for(int j = 0 ; j <= 26 ; ++j) { nxt[i][j] = N + 1; } } for(int i = 0 ; i <= N + 1 ; ++i) { for(int j = 0 ; j <= 19 ; ++j) ri[i][j] = N + 1; } for(int i = N - 1 ; i >= 0 ; --i) { int x = s[i + 1] - 'a'; nxt[i][x] = i + 1; for(int j = x + 1 ; j <= 26 ; ++j) { nxt[i][j] = nxt[nxt[i][j - 1]][j - 1]; } for(int j = 0 ; j < x ; ++j) { nxt[i][j] = nxt[nxt[i][26]][j]; } } for(int j = 0 ; j <= 19 ; ++j) { for(int i = N - 1 ; i >= 0 ; --i) { if(j == 0) ri[i][j] = nxt[i][26]; else ri[i][j] = ri[ri[i][j - 1]][j - 1]; } } int Q; read(Q); int l,r; for(int i = 1 ; i <= Q ; ++i) { read(l);read(r); --l; for(int j = 19 ; j >= 0 ; --j) { if(ri[l][j] <= r) l = ri[l][j]; } if(l == r) puts("Yes"); else puts("No"); } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
顯然D是直徑上取整class
而後咱們給每一個點作一個標號,任取一個點\(h(v) = 0\)date
若是\(u\rightarrow v\)有一條邊那麼\(h(v) - h(u) = 1\)
最後能夠定義\(d(s,t) = (dist(s,t) + h(s) - h(t))/ 2\)
若是直徑是偶數,那麼能夠發現
\(|h(s) - h(t)| \leq 2D - dist(s,t)\)
找到直徑的中心\(r\),距離中心距離爲\(D\)的點,顯然標號應該同樣,假設標號都是0,咱們能夠獲得任意一點u都有\(|h(u)| \leq D - dist(r,u)\)
這個是必要的,也是充分的,對於任意兩點\(u,v\)
\(|h(u) - h(v)| \leq |h(u)| + |h(v)| \leq 2D - dist(r,u) - dist(r,v) \leq 2D - dist(u,v)\)
因此咱們認爲\(|h(u)| \leq D - dist(r,u)\),作一個dp,能夠獲得全部解
若是直徑是奇數,就有了兩個中心,一個是s,一個是t
咱們認爲\(dist(u,s) < dist(t,u)\)的是白點,不然是黑點,那麼有兩種狀況
若是u是白點,\(|h(u)| \leq D - 1 - dist(u,s)\)
若是u是黑點,\(|h(u)| \leq D - dist(u,t)\)
或者
u是白點,\(|h(u)| \leq D - dist(u,s)\)
u是黑點,\(|h(u)| \leq D - 1 - dist(u,t)\)
可是這兩種狀況有交集
就是白點的距離s最遠的點全是0,另外一邊距離最遠的全是-1,或者全是+1,這個時候咱們若是全部點同時-1或者同時+1,會發現這兩種狀況等價可是咱們重複統計了
這個時候條件是
u是白點,\(|h(u)| \leq D - dist(u,s)\)
u是黑點,\(|h(u) + 1| \leq D - dist(u,t)\)
或者是
u是白點,\(|h(u)| \leq D - dist(u,s)\)
u是黑點,\(|h(u) - 1| \leq D - dist(u,t)\)
#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 1005 //#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,V = 505; struct node { int to,next; }E[MAXN * 2]; int sumE,head[MAXN]; int N; int dis[MAXN],fa[MAXN],D; int dp[MAXN][MAXN * 2]; 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); } void add(int u,int v) { E[++sumE].to = v; E[sumE].next = head[u]; head[u] = sumE; } void dfs(int u) { for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(v != fa[u]) { fa[v] = u; dis[v] = dis[u] + 1; dfs(v); } } } void dfs1(int u,int lim,int on) { for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(v != fa[u]) { dfs1(v,lim,on); } } int l = dis[u] - lim - on,r = lim - dis[u] - on; for(int i = l + V ; i <= r + V; ++i) { dp[u][i] = 1; for(int j = head[u] ; j ; j = E[j].next) { int v = E[j].to; if(v != fa[u]) { int t = inc(dp[v][i - 1],dp[v][i + 1]); dp[u][i] = mul(dp[u][i],t); } } } } int Process_even(int rt) { fa[rt] = 0;dis[rt] = 0; dfs(rt); memset(dp,0,sizeof(dp)); dfs1(rt,D,0); int ans = 0; for(int i = 0 ; i <= V * 2 ; ++i) { update(ans,dp[rt][i]); } return ans; } int Process_odd(int s,int t,int on) { fa[s] = t;fa[t] = s;dis[s] = 0;dis[t] = 0; dfs(s);dfs(t); memset(dp,0,sizeof(dp)); dfs1(s,D - 1,0); dfs1(t,D,on); int ans = 0; for(int i = 1 ; i <= V * 2 ; ++i) { update(ans,mul(dp[s][i],inc(dp[t][i - 1],dp[t][i + 1]))); } return ans; } void Solve() { read(N); int a,b; for(int i = 1 ; i < N ; ++i) {read(a);read(b);add(a,b);add(b,a);} dis[1] = 0;fa[1] = 0;dfs(1); int u = 1; for(int i = 2 ; i <= N ; ++i) { if(dis[i] > dis[u]) u = i; } dis[u] = 0;fa[u] = 0; dfs(u); u = 1; for(int i = 2 ; i <= N ; ++i) { if(dis[i] > dis[u]) u = i; } if(dis[u] % 2 == 0) { int r = u; for(int i = 1 ; i <= dis[u] / 2 ; ++i) r = fa[r]; D = dis[u] / 2; int ans = Process_even(r); out(ans);enter; } else { int s = u; for(int i = 1 ; i <= dis[u] / 2 ; ++i) s = fa[s]; int t = fa[s]; D = dis[u] / 2 + 1; int ans = inc(Process_odd(s,t,0),Process_odd(t,s,0)); update(ans,MOD - Process_odd(s,t,-1)); update(ans,MOD - Process_odd(s,t,1)); out(ans);enter; } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }