前一枚舉一個i,求第一行的前i個和第二行從第n個到第i個node
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define pdi pair<db,int> #define mp make_pair #define pb push_back #define enter putchar('\n') #define space putchar(' ') #define eps 1e-8 #define mo 974711 #define MAXN 1000005 //#define ivorysi using namespace std; typedef long long int64; typedef double db; 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) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } int N,sum[2][105]; void Solve() { read(N); for(int i = 0 ; i <= 1 ; ++i) { for(int j = 1 ; j <= N ; ++j) { read(sum[i][j]); } } for(int i = 1 ; i <= N ; ++i) { sum[0][i] += sum[0][i - 1]; } for(int i = N ; i >= 1 ; --i) { sum[1][i] += sum[1][i + 1]; } int ans = 0; for(int i = 1 ; i <= N ; ++i) { ans = max(ans,sum[0][i] + sum[1][i]); } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
帶權並查集,維護每一個點到父親節點的距離便可c++
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define pdi pair<db,int> #define mp make_pair #define pb push_back #define enter putchar('\n') #define space putchar(' ') #define eps 1e-8 #define mo 974711 #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; typedef double db; 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) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } int N,M; int fa[MAXN],dis[MAXN]; int getfa(int u) { if(u == fa[u]) return u; else { int t = getfa(fa[u]); dis[u] += dis[fa[u]]; return fa[u] = t; } } void Solve() { read(N);read(M); for(int i = 1 ; i <= N ; ++i) { fa[i] = i;dis[i] = 0; } int l,r,d; for(int i = 1 ; i <= M ; ++i) { read(l);read(r);read(d); if(getfa(l) == getfa(r)) { if(dis[r] - dis[l] != d) { puts("No"); return; } } else { int p = getfa(r),q = getfa(l); fa[p] = q; dis[p] = dis[l] - dis[r] + d; } } puts("Yes"); } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
先計算全部的狀況,再計算不合法的狀況
枚舉在邊上撞上的狀況,很容易發現兩我的撞上只會在一條邊上撞上,且若是在這條邊撞上在包括這條邊的全部路徑裏其餘邊都不會再撞上,而後計算穿過這條邊\(u,v\)的方案數,是從\(S\)到\(u\)和從\(v\)到\(T\)的方案數相乘git
而後枚舉在點撞上的狀況,是到\(S\)和到\(T\)最短路距離相同的點spa
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define pdi pair<db,int> #define mp make_pair #define pb push_back #define enter putchar('\n') #define space putchar(' ') #define eps 1e-8 #define mo 974711 #define MAXN 200005 //#define ivorysi using namespace std; typedef long long int64; typedef double db; 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) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } const int MOD = 1000000007; int N,M,S,T; struct node { int to,next; int64 val; }E[MAXN * 2]; int head[MAXN],sumE,id[MAXN],on,dp[2][MAXN],ans; int64 dis[2][MAXN]; bool vis[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 add(int u,int v,int64 c) { E[++sumE].to = v; E[sumE].next = head[u]; E[sumE].val = c; head[u] = sumE; } priority_queue<pair<int64,int> > Q; void dijkstra(int u,int64 *d) { for(int i = 1 ; i <= N ; ++i) d[i] = 1e18; memset(vis,0,sizeof(vis)); d[u] = 0; Q.push(mp(-d[u],u)); while(!Q.empty()) { pair<int64,int> now = Q.top();Q.pop(); if(vis[now.se]) continue; int u = now.se; vis[u] = 1; for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(!vis[v] && d[v] > d[u] + E[i].val) { d[v] = d[u] + E[i].val; Q.push(mp(-d[v],v)); } } } } bool cmp(int a,int b) { return dis[on][a] < dis[on][b]; } void Process() { for(int i = 1 ; i <= N ; ++i) id[i] = i; sort(id + 1,id + N + 1,cmp); dp[on][id[1]] = 1; for(int i = 1 ; i <= N ; ++i) { int u = id[i]; for(int j = head[u] ; j ; j = E[j].next) { int v = E[j].to; if(dis[on][v] - dis[on][u] == E[j].val) { dp[on][v] = inc(dp[on][v],dp[on][u]); } } } } void Solve() { read(N);read(M); read(S);read(T); int u,v;int64 d; for(int i = 1 ; i <= M ; ++i) { read(u);read(v);read(d); add(u,v,d);add(v,u,d); } dijkstra(S,dis[0]); dijkstra(T,dis[1]); on = 0;Process(); on = 1;Process(); ans = mul(dp[0][T],dp[0][T]); for(int u = 1 ; u <= N ; ++u) { for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(dis[0][u] + dis[1][v] + E[i].val == dis[0][T]) { if(dis[1][v] + E[i].val - dis[0][u] > 0 && dis[1][v] + E[i].val - dis[0][u] < 2 * E[i].val) { ans = inc(ans,MOD - mul(mul(dp[0][u],dp[1][v]),mul(dp[1][v],dp[0][u]))); } } } if(dis[0][u] == dis[1][u]) { ans = inc(ans,MOD - mul(mul(dp[0][u],dp[1][u]),mul(dp[0][u],dp[1][u]))); } } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
考慮一下數的個數最多不超過10^8個code
若是開頭的數數位是8或以上,最多隻進一次位
咱們從1到\(\frac{S}{8}\)枚舉位數,設開頭的數數位爲a
若是全爲數位長爲a的數,若是有i個,就是\(10^{a} - 10^{a - 1} - i + 1\)
不然就是\(1\)rem
而後咱們枚舉開頭數位是1到7,枚舉跨了幾個數位,最可能是跨到8
而後枚舉\(10^a - 10^{a - 1}\)爲我開頭數位選了幾個,計算終點數位可否被整除,選的個數符不符合要求,不斷+1便可get
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define pdi pair<db,int> #define mp make_pair #define pb push_back #define enter putchar('\n') #define space putchar(' ') #define eps 1e-8 #define mo 974711 #define MAXN 200005 //#define ivorysi using namespace std; typedef long long int64; typedef double db; 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) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } const int MOD = 1000000007; int S; int pw[15],sum[15]; 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 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 update(int &x,int y) { x = inc(x,y); } void Solve() { read(S); pw[0] = 1; for(int i = 1 ; i <= 8 ; ++i) { pw[i] = pw[i - 1] * 10; sum[i] = (pw[i] - pw[i - 1]) * i; sum[i] += sum[i - 1]; } int T = min(S,20000000); int ans = 0; for(int i = 1 ; i <= T ; ++i) { int a = S / i; if(a >= 8) { if(S % i == 0) { update(ans,inc(inc(fpow(10,a),MOD - fpow(10,a - 1)),MOD - i + 1)); } else { update(ans,1); } } else break; } for(int a = 1 ; a <= 7 ; ++a) { if(S < a) break; if(S % a == 0 && S / a <= pw[a] - pw[a - 1]) update(ans,pw[a] - pw[a - 1] - S / a + 1); for(int b = 1 ; b <= 7 ; ++b) { if(a + b >= 9) break; if(sum[a + b] - sum[a - 1] < S) continue; int t = sum[a + b - 1] - sum[a]; if(t > S) break; int rem = S - t; for(int i = 1 ; i <= pw[a] - pw[a - 1] ; ++i) { if(i * a >= rem) break; if((rem - i * a) % (a + b) == 0) { if((rem - (i * a)) / (a + b) <= pw[a + b] - pw[a + b - 1]) update(ans,1); } } } } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }