發現符文的相對位置不變,直接二分某個位置是否到達最左或最右來計算c++
#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); } int N,Q; char s[MAXN]; pii op[MAXN]; int getplace(int p) { for(int i = 1 ; i <= Q ; ++i) { if(s[p] == 'A' + op[i].fi) { p += op[i].se; } } return p; } int findL() { int L = 0,R = N; while(L < R) { int mid = (L + R + 1) >> 1; if(getplace(mid) == 0) L = mid; else R = mid - 1; } return L; } int findR() { int L = 1,R = N + 1; while(L < R) { int mid = (L + R) >> 1; if(getplace(mid) == N + 1) R = mid; else L = mid + 1; } return L; } void Solve() { read(N);read(Q); scanf("%s",s + 1); char t[5],d[5]; for(int i = 1 ; i <= Q ; ++i) { scanf("%s%s",t + 1,d + 1); int a,b; if(d[1] == 'L') b = -1; else b = 1; a = t[1] - 'A'; op[i] = mp(a,b); } int L = findL(),R = findR(); out(R - L - 1);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
若是按照咱們對值產生貢獻的序列必定是一個遞減的序列spa
咱們只要按照值從大到小排序後記錄\(dp[i][j]\)爲到第i個數取模的數是j的機率是多少code
轉移的時候若是對當前值進行取模,則乘上一個\(\frac{1}{N - i + 1}\)排序
不然取乘一個\(\frac{N- i}{N - i + 1}\)get
#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); } const int MOD = 1000000007; int N,X,a[205],fac[205],inv[205]; int dp[205][100005]; 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);read(X); for(int i = 1 ; i <= N ; ++i) read(a[i]); sort(a + 1,a + N + 1,[](int a,int b){return a > b;}); fac[0] = 1; for(int i = 1 ; i <= N ; ++i) fac[i] = mul(fac[i - 1],i); inv[1] = 1; for(int i = 2 ; i <= N ; ++i) inv[i] = mul(inv[MOD % i],MOD - MOD / i); dp[0][X] = 1; for(int i = 1 ; i <= N ; ++i) { for(int j = 0 ; j <= X ; ++j) { if(j < a[i]) update(dp[i][j],dp[i - 1][j]); else { update(dp[i][j % a[i]],mul(dp[i - 1][j],inv[N - i + 1])); update(dp[i][j],mul(dp[i - 1][j],mul(N - i,inv[N - i + 1]))); } } } int ans = 0; for(int j = 0 ; j <= X ; ++j) { update(ans,mul(dp[N][j],j)); } ans = mul(ans,fac[N]); out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
咱們把點畫在座標軸上,每一個i至關於畫一條斜線,那麼若是這個斜線上的點都有讓B減小的一步,那麼答案就是\(\frac{1}{2}\)it
不然處理出剩了多少個白點,和剩了多少個黑點的狀況,每條斜線最多涉及兩個這樣的點,把他們的貢獻加上或減掉便可io
#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); } const int MOD = 1000000007; int B,W; int fac[MAXN],invfac[MAXN],pw[MAXN]; int r[MAXN],c[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; } int C(int n,int m) { if(n < m) return 0; return mul(fac[n],mul(invfac[m],invfac[n - m])); } int fpow(int x,int c) { int res = 1,t = x; while(c) { if(c & 1) res = mul(res,t); t = mul(t,t); c >>= 1; } return res; } void Solve() { read(B);read(W); fac[0] = 1; for(int i = 1 ; i <= B + W ; ++i) fac[i] = mul(fac[i - 1],i); invfac[B + W] = fpow(fac[B + W],MOD - 2); for(int i = B + W - 1 ; i >= 0 ; --i) invfac[i] = mul(invfac[i + 1],i + 1); pw[0] = 1;pw[1] = invfac[2]; for(int i = 2 ; i <= B + W ; ++i) pw[i] = mul(pw[i - 1],pw[1]); r[0] = pw[W]; for(int i = 1; i <= B ; ++i) { r[i] = inc(r[i - 1],mul(pw[1],mul(pw[i + W - 1],C(i + W - 1,i)))); } c[0] = pw[B]; for(int i = 1 ; i <= W ; ++i) { c[i] = inc(c[i - 1],mul(pw[1],mul(pw[B - 1 + i],C(B - 1 + i,i)))); } for(int i = 0 ; i < B + W ; ++i) { int res = (MOD + 1) / 2; if(i >= B) { res = inc(res,MOD - mul((MOD + 1) / 2,c[i - B])); } if(i >= W) { res = inc(res,mul((MOD + 1) / 2,r[i - W])); } out(res);enter; } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }