點燃的必定是連續的一段,枚舉左端點便可node
#include <bits/stdc++.h> #define enter putchar('\n') #define space putchar(' ') #define pii pair<int,int> #define fi first #define se second #define mp make_pair #define MAXN 1000005 #define mo 999999137 #define pb push_back //#define ivorysi using namespace std; typedef long long int64; 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 a[100005]; int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif read(N);read(K); for(int i = 1 ; i <= N ; ++i) { read(a[i]); } int64 ans = 1e16; for(int i = 1 ; i <= N - K + 1; ++i) { int t = i + K - 1; if(1LL * a[i] * a[t] > 0) { ans = min(ans,max(abs(a[i]),abs(a[t]))); } else ans = min(ans,min(-2 * a[i] + a[t],2 * a[t] - a[i])); } out(ans);enter; return 0; }
二分一個值做爲中位數的中位數,把大於這個數的設成1,小於等於這個數的設成0
而後咱們就須要知道小於等於這個數作中位數的區間有多少個,用樹狀數組維護,和所有區間個數的一半比較一下便可ios
#include <bits/stdc++.h> #define enter putchar('\n') #define space putchar(' ') #define pii pair<int,int> #define fi first #define se second #define mp make_pair #define MAXN 1000005 #define mo 999999137 #define pb push_back //#define ivorysi using namespace std; typedef long long int64; 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; int64 M; int a[100005],num[100005],cnt; int sum[100005][2],c[200005]; int tr[200005]; int lowbit(int x) {return x & -x;} void Insert(int x,int v) { while(x <= 2 * N + 1) { tr[x] += v; x += lowbit(x); } } int Query(int x) { int res = 0; while(x > 0) { res += tr[x]; x -= lowbit(x); } return res; } bool check(int x) { for(int i = 1 ; i <= N ; ++i) { sum[i][0] = sum[i - 1][0] + (a[i] <= x); sum[i][1] = sum[i - 1][1] + (a[i] > x); } memset(tr,0,sizeof(tr)); for(int i = 1 ; i <= N ; ++i) Insert(sum[i][1] - sum[i][0] + N + 1,1); int64 res = 0; for(int i = 1 ; i <= N ; ++i) { int t = sum[i - 1][1] - sum[i - 1][0] + N + 1; res += Query(t - 1); Insert(sum[i][1] - sum[i][0] + N + 1,-1); } return res >= M; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif read(N); for(int i = 1 ; i <= N ; ++i) {read(a[i]);num[i] = a[i];} M = 1LL * N * (N + 1) / 2; M = M / 2 + 1; sort(num + 1,num + N + 1); cnt = unique(num + 1,num + N + 1) - num - 1; int L = 1,R = cnt; while(L < R) { int mid = (L + R) >> 1; if(check(num[mid])) R = mid; else L = mid + 1; } out(num[L]);enter; return 0; }
咱們用容斥來考慮,設\(g(i)\)爲至少有i條邊沒有被覆蓋的方案數,那麼答案就是
\(\sum_{i = 1}^{n} (-1)^{i}g(i)\)考慮一邊dp一邊求g的係數
用dp[u][i][0/1]表示以u爲根的子樹裏,i個點匹配了,係數爲-1或1的方案數c++
轉移的話用相似樹揹包的轉移
若是不是根的話枚舉父邊是否是沒有被覆蓋數組
#include <bits/stdc++.h> #define enter putchar('\n') #define space putchar(' ') #define pii pair<int,int> #define fi first #define se second #define mp make_pair #define MAXN 5005 #define mo 99994711 #define pb push_back //#define ivorysi using namespace std; typedef long long int64; 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; struct node { int to,next; }E[MAXN * 2]; int head[MAXN],sumE; int dp[MAXN][MAXN][2],fac[MAXN],inv[MAXN],invfac[MAXN],p[MAXN],siz[MAXN],tmp[MAXN][2]; void add(int u,int v) { E[++sumE].to = v; E[sumE].next = head[u]; head[u] = sumE; } int mul(int a,int b) { return 1LL * a * b % MOD; } int inc(int a,int b) { return a + b >= MOD ? a + b - MOD : a + b; } void update(int &x,int y) { x = inc(x,y); } int C(int n,int m) { if(n < m) return 0; return mul(fac[n],mul(invfac[m],invfac[n - m])); } void dfs(int u,int fa) { dp[u][0][0] = 1; siz[u] = 0; for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(v != fa) { dfs(v,u); for(int i = 0 ; i <= siz[u] + siz[v] ; ++i) tmp[i][0] = tmp[i][1] = 0; for(int i = 0 ; i <= siz[u] ; ++i) { for(int j = 0 ; j <= siz[v] ; ++j) { for(int k = 0 ; k <= 1 ; ++k) { for(int h = 0 ; h <= 1 ; ++h) { update(tmp[i + j][k ^ h],mul(dp[u][i][k],dp[v][j][h])); } } } } for(int i = 0 ; i <= siz[u] + siz[v] ; ++i) { dp[u][i][0] = tmp[i][0]; dp[u][i][1] = tmp[i][1]; } siz[u] += siz[v]; } } ++siz[u]; if(fa) { for(int i = siz[u] - 1; i >= 0 ; --i) { for(int k = 0 ; k <= 1 ; ++k) { update(dp[u][siz[u]][k],mul(dp[u][i][k ^ 1],p[siz[u] - i])); } } } } void Solve() { read(N); int u,v; for(int i = 1 ; i < N ; ++i) { read(u);read(v);add(u,v);add(v,u); } inv[1] = 1; for(int i = 2 ; i <= N ; ++i) inv[i] = mul(inv[MOD % i],MOD - MOD / i); fac[0] = invfac[0] = 1; for(int i = 1 ; i <= N ; ++i) fac[i] = mul(fac[i - 1],i),invfac[i] = mul(invfac[i - 1],inv[i]); p[0] = 1; for(int i = 1 ; i <= N ; ++i) { if(i & 1) p[i] = 0; else p[i] = mul(p[i - 2],i - 1); } dfs(1,0); int ans = 0; for(int i = 0 ; i <= N ; ++i) { ans = inc(ans,mul(dp[1][i][0],p[N - i])); ans = inc(ans,MOD - mul(dp[1][i][1],p[N - i])); } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
把每一個機器人到左邊最近的距離記做\(a_i\),到右邊最近的距離記做\(b_i\)spa
咱們把這個點\((a_i,b_i)\)畫在平面直角座標系裏code
而後咱們記\((x,y)\)爲最左的點遠離初始點x的距離,到過最右的點遠離初始點y的距離
每次能夠走到\((x + 1,y)\)或\((x,y + 1)\)
在路徑下方的點是從右邊出口走的,上方的點是從左邊出口走的get
咱們就是要看走的折線能把點分紅幾個集合,用樹狀數組維護來轉移便可string
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #define enter putchar('\n') #define space putchar(' ') #define fi first #define se second #define mp make_pair #define MAXN 100005 //#define ivorysi #define pii pair<int,int> using namespace std; typedef long long int64; 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) {putchar('-');x = -x;} if(x >= 10) out(x / 10); putchar('0' + x % 10); } const int MOD = 1000000007; int N,M; int x[MAXN],y[MAXN],tot,v[MAXN],cnt,tr[MAXN],f[MAXN]; pii poi[MAXN]; int lowbit(int x) { return x & -x; } 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 Insert(int x,int v) { while(x <= cnt) { tr[x] = inc(tr[x],v); x += lowbit(x); } } int Query(int x) { int res = 0; while(x > 0) { res = inc(res,tr[x]); x -= lowbit(x); } return res; } void Solve() { read(N);read(M); for(int i = 1 ; i <= N ; ++i) read(x[i]); for(int i = 1 ; i <= M ; ++i) read(y[i]); int p = 1; for(int i = 1 ; i <= N ; ++i) { while(p + 1 <= M && y[p + 1] < x[i]) ++p; if(p >= M) break; if(x[i] > y[p]) poi[++tot] = mp(x[i] - y[p],y[p + 1] - x[i]); } sort(poi + 1,poi + tot + 1); tot = unique(poi + 1,poi + tot + 1) - poi - 1; for(int i = 1 ; i <= tot ; ++i) { v[++cnt] = poi[i].se; } v[++cnt] = 0; sort(v + 1,v + cnt + 1); cnt = unique(v + 1,v + cnt + 1) - v - 1; Insert(1,1); int ans = 1;p = 0; for(int i = 1 ; i <= tot ; ++i) { while(p + 1 <= tot && poi[p + 1].fi < poi[i].fi) { ++p; int t = lower_bound(v + 1,v + cnt + 1,poi[p].se) - v; Insert(t,f[p]); } int t = lower_bound(v + 1,v + cnt + 1,poi[i].se) - v; f[i] = Query(t - 1); ans = inc(ans,f[i]); } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }