• 牛客小白月赛16


    A.只有1个的时候后手胜,其他先手胜

    没证明,手推了前几个先手胜的看榜上过穿了就交了

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++) 
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f)) 
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x); 
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x); 
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long 
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
    while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
    const double eps = 1e-9;
    const int maxn = 110;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    int N,M,K;
    int main(){
        Sca(N);
        if(N == 1) puts("Yang");
        else puts("Shi");
        return 0;
    }
    A

    B.按照题意暴力递推出来,求个每一层的前缀和

    pre[r] - pre[l - 1]直接计算

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++) 
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f)) 
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x); 
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x); 
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long 
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
    while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
    const double eps = 1e-9;
    const int maxn = 1010;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    int N,M,K;
    LL MAP[maxn][maxn];
    LL pre[maxn];
    int main(){
        Sca2(N,M);
        pre[1] = 1;
        for(int i = 2; i <= N ; i ++){
            MAP[i][1] = MAP[i][i] = i;
            pre[i] = (2 * i + pre[i - 1]) % mod;
            for(int j = 2; j < i ; j ++){
                MAP[i][j] = (MAP[i - 1][j] + MAP[i - 1][j - 1]) % mod;
                pre[i] += MAP[i][j]; pre[i] %= mod;
            }
        }
        while(M--){
            int l,r; Sca2(l,r);
            Prl((pre[r] - pre[l - 1] + mod) % mod);
        }
        return 0;
    }
    B

    C.题目写的花里胡哨仿佛要上数据结构

    看了一眼范围暴力可过

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++) 
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f)) 
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x); 
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x); 
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long 
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
    while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
    const double eps = 1e-9;
    const int maxn = 1010;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    int N,M,K;
    int a[maxn];
    int main(){
        Sca2(N,M);
        for(int i = 1; i <= N ; i ++) Sca(a[i]);
        while(M--){
            int x; Sca(x);
            int ans = 0;
            int cnt = 0;
            for(int i = 1; i <= N ; i ++){
                if(x >= a[i]){
                    cnt = 0;
                    continue;
                }
                if(!cnt){
                    cnt = 1; ans++;
                }
            }
            Pri(ans);
        }
        return 0;
    }
    C

    D.感觉尺取可以做。

    但我还是离散了一下前缀和,树状数组维护比当前前缀和小的最小的位置。nlogn直接做

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++) 
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f)) 
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x); 
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x); 
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long 
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
    while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
    const double eps = 1e-9;
    const int maxn = 2e6 + 1110;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    int N,M,K;
    int a[maxn],pre[maxn];
    int Hash[maxn];
    int tree[maxn];
    void add(int u,int v){
        for(;u <= N; u += u & -u) tree[u] = min(tree[u],v);
    }
    int getmin(int u){
        int ans = INF;
        for(;u > 0; u -= u & -u) ans = min(ans,tree[u]);
        return ans;
    }
    int main(){
        Sca(N);
        int cnt = 0;
        for(int i = 0 ;i <= N + 1; i ++) tree[i] = INF;
        for(int i = 1; i <= N ; i ++){
            Sca(a[i]); pre[i] = pre[i - 1] + a[i];
            Hash[++cnt] = pre[i];
        }
        Hash[++cnt] = 0;
        sort(Hash + 1,Hash + 1 + cnt);
        cnt = unique(Hash + 1,Hash + 1 + cnt) - Hash - 1;
        int x = lower_bound(Hash + 1,Hash + 1 + cnt,0) - Hash;
        add(x,0);
        int ans = 0;
        for(int i = 1; i <= N; i ++){
            pre[i] = lower_bound(Hash + 1,Hash + 1 + cnt,pre[i]) - Hash;
            add(pre[i],i);
            ans = max(ans,i - getmin(pre[i] - 1));
        }
        Pri(ans);
        return 0;
    }
    D

    E.这个数据范围的意思就是告诉你直接BFS递推就可以了

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++) 
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f)) 
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x); 
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x); 
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long 
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
    while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
    const double eps = 1e-9;
    const int maxn = 10010;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    int N,M,K;
    bool vis[10][10][maxn];
    int MAP[10][10];
    struct node{
        int x,y,sum;
        node(){}
        node(int x,int y,int sum):x(x),y(y),sum(sum){}
    };
    const int a[2][2] = {0,1,1,0};
    bool check(int x,int y){
        return 1 <= x && x <= N && 1 <= y &&y <= N;
    }
    int main(){
        Sca(N);
        for(int i = 1; i <= N ; i ++){
            for(int j = 1; j <= N; j ++){
                Sca(MAP[i][j]);
            }
        }
        queue<node>Q; Q.push(node(1,1,MAP[1][1]));
        vis[1][1][MAP[1][1]] = 1;
        while(!Q.empty()){
            node u = Q.front(); Q.pop();
            for(int i = 0 ; i < 2; i ++){
                node h = u;
                h.x += a[i][0]; h.y += a[i][1];
                if(!check(h.x,h.y)) continue;
                h.sum += MAP[h.x][h.y];
                if(!vis[h.x][h.y][h.sum]){
                    vis[h.x][h.y][h.sum] = 1;
                    Q.push(h);
                }
            }
        }
        int ans = 0;
        for(int i = 0 ; i < maxn; i ++){
            if(vis[N][N][i]) ans++;
        }
        Pri(ans);
        return 0;
    }
    E

    F.题目里说每个大兄弟的两个属性两两之间互不相同,这很重要

    按照第一关键字从大到小排序,那么每一趟就相当于在所有大兄弟里找一个第二关键字递增的序列

    暴力n ^ 2肯定不行,想办法优化就可以了,我这边先预处理nxt[i]表示下一个比这个位置的第二关键字高的位置,然后查询的时候i直接跳nxt[i]

    然后并查集维护所有已经被选择过的大兄弟就可以了

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++) 
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f)) 
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x) 
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x) 
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long 
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
    while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
    const double eps = 1e-9;
    const int maxn = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    int N,M,K;
    struct node{
        int fi,se,id;
    }girl[maxn];
    int fa[maxn];
    void init(){
        for(int i = 1; i <= N + 1; i ++) fa[i] = i;
    }
    int find(int x){
        return x == fa[x]?x:fa[x] = find(fa[x]);
    }
    void Union(int a,int b){
        a = find(a); b = find(b);
        fa[a] = b;
    }
    int nxt[maxn];
    int ans[maxn];
    bool cmp(node a,node b){
        return a.fi > b.fi;
    }
    int main(){
        Sca(N); init();
        for(int i = 1; i <= N ; i ++){
            Sca2(girl[i].fi,girl[i].se);
            girl[i].id = i;
        }
        sort(girl + 1,girl + 1 + N,cmp);
        girl[N + 1].se = INF;
        for(int i = N; i >= 1; i --){
            int to = i + 1;
            while(girl[i].se > girl[to].se){
                to = nxt[to];
            }
            nxt[i] = to;
        }
        int tot = 0;
        while(1){
            tot++;
            int s = find(1);
            if(s == N + 1) break;
            int high = girl[s].se;
            while(s != N + 1){
                Union(s,s + 1);
                ans[girl[s].id] = tot;
                high = girl[s].se;
                while(s != N + 1 && girl[s].se <= high) s = find(nxt[s]);
            }
        }  
        for(int i = 1; i <= N ; i ++) Pri(ans[i]);
        return 0;
    }
    F

    G.小学数学

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++) 
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f)) 
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x); 
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x); 
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long 
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
    while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
    const double eps = 1e-9;
    const int maxn = 110;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    int N,M,K;
    double PI = acos(-1.0);
    int main(){
        double N;
        cin >> N;
        printf("%.3lf",N * N / (2 * PI));
        return 0;
    }
    G

    H. 

    gcd(a1,a2,a3,a4 .. ,an) = gcd(a1,a2 - a1,a3 - a2,a4 - a3,....an - an - 1)

    通过上面这个式子,可以把区间维护gcd变成区间维护差分序列的gcd,乍一看还是区间gcd,但是差分序列的维护就直接从区间修改降到了单点修改。

    凑巧的是区间差的最大值也可以直接维护一个差分序列的最大值,再用树状数组维护一下原序列(因为上面式子右边还有一个a1,这不是差分) 

    这道题就解决了

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++) 
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f)) 
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x) 
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x) 
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long 
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
    while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
    const double eps = 1e-9;
    const int maxn = 3e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    int N,M,K;
    LL gcd(LL a,LL b){
        return b == 0?a:gcd(b,a % b);
    }
    LL a[maxn];
    struct Tree{
        int l,r;
        LL Gcd,Max,real;
    }tree[maxn << 2];
    void Pushup(int t){
        tree[t].Gcd = gcd(tree[t << 1].Gcd,tree[t << 1 | 1].Gcd);
        tree[t].Max = max(tree[t << 1].Max,tree[t << 1 | 1].Max);
    }
    void Build(int t,int l,int r){
        tree[t].l = l; tree[t].r = r;
        if(l == r){
            tree[t].real = a[r] - a[r - 1];
            tree[t].Gcd = tree[t].Max = abs(tree[t].real);
            return;
        }
        int m = l + r >> 1;
        Build(t << 1,l,m); Build(t << 1 | 1,m + 1,r);
        Pushup(t);
    }
    void update(int t,int p,LL v){
        if(tree[t].l == tree[t].r){
            tree[t].real += v;
            tree[t].Gcd = tree[t].Max = abs(tree[t].real);
            return;
        }
        int m = tree[t].l + tree[t].r >> 1;
        if(p <= m) update(t << 1,p,v);
        else update(t << 1 | 1,p,v);
        Pushup(t);
    }
    LL queryMax(int t,int l,int r){
        if(l <= tree[t].l && tree[t].r <= r){
            return tree[t].Max;
        }
        int m = tree[t].l + tree[t].r >> 1;
        if(r <= m) return queryMax(t << 1,l,r);
        else if(l > m) return queryMax(t << 1 | 1,l,r);
        else{
            return max(queryMax(t << 1,l,m),queryMax(t << 1 | 1,m + 1,r));
        }
    }
    LL queryGcd(int t,int l,int r){
        if(l <= tree[t].l && tree[t].r <= r){
            return tree[t].Gcd;
        }
        int m = tree[t].l + tree[t].r >> 1;
        if(r <= m) return queryGcd(t << 1,l,r);
        else if(l > m) return queryGcd(t << 1 | 1,l,r);
        else{
            return gcd(queryGcd(t << 1,l,m),queryGcd(t << 1 | 1,m + 1,r));
        }
    }
    LL BIT[maxn];
    void add(int x,LL v){
        for(;x <= N + 10;x += x & -x) BIT[x] += v;
    }
    LL getsum(int x){
        LL ans = 0;
        for(;x > 0;x -= x & -x) ans += BIT[x];
        return ans;
    }
    int main(){
        Sca2(N,M);
        for(int i = 1; i <= N ; i ++){
             Scl(a[i]);
             add(i,a[i]); add(i + 1,-a[i]);
        }
        Build(1,2,N);
        while(M--){
            int op,l,r; Sca3(op,l,r);
            if(op == 1){
                LL x; Scl(x);
                if(l != 1) update(1,l,x);
                if(r != N) update(1,r + 1,-x);
                add(l,x); add(r + 1,-x);
            }else if(op == 2){
                if(l == r) puts("0");
                else Prl(queryMax(1,l + 1,r));
            }else{
                LL x = getsum(l);
                if(l == r) Prl(x);
                else Prl(gcd(x,queryGcd(1,l + 1,r)));
            }
        }
        return 0;
    }
    H

    I.数论一生黑,不会

    补: 第一步前进的期望dp[1]是1 / a,(因为不会后退)

    后面每一步前进的期望dp[i] = 1 (摇到前进) + b / a (摇到平局) + c / a * (dp[i - 1] + 1) (摇到后退,代价是摇了一下后退并且需要再上来)

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x)  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x)  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
    while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
    const double eps = 1e-9;
    const int maxn = 110;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    LL dp[maxn];
    LL quick_power(LL a,LL b){
        LL ans = 1;
        while(b){
            if(b & 1) ans = ans * a % mod;
            b >>= 1;
            a = a * a % mod;
        }
        return ans;
    }
    LL inv(LL x){
        return quick_power(x,mod - 2);
    }
    int main(){
        LL n,a,b;
        cin >> n >> a >> b;
        LL ans = dp[1] = inv(a);
        LL c = ((1 - a - b) % mod + mod) % mod;
        for(int i = 2; i < n; i ++){
            dp[i] = 1 + c * inv(a) % mod * (1 + dp[i - 1]) % mod + b * inv(a) % mod;
            dp[i] %= mod;
            ans = (ans + dp[i]) % mod; 
        }
        Prl(ans);
        return 0;
    }
    I

    J.似乎只是个略微麻烦点的裸最短路罢了,dis[i][j]表示第i条线路第j个站点的最少花费,Dijkstra直接上就好了

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++) 
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f)) 
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x) 
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x) 
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long 
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
    while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
    const double eps = 1e-9;
    const int maxn = 1010;
    const int maxm = 510;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    int N,M,s,t;
    int a[maxm],b[maxm];
    int nxt[maxm][maxn],pre[maxm][maxn];
    int tmp[maxn];
    vector<int>P[maxn];
    LL dis[maxm][maxn];
    struct node{
        int n,m;
        LL val;
        node(){}
        node(int n,int m,LL val):n(n),m(m),val(val){}
        friend bool operator < (node a,node b){
            return a.val > b.val;
        }
    };
    void Dijkstra(){
        for(int i = 0 ; i <= M; i ++){
            for(int j = 0 ; j <= N ; j ++) dis[i][j] = 1e18;
        }
        dis[0][s] = 0;
        priority_queue<node>Q; Q.push(node(s,0,0));
        while(!Q.empty()){
            node u = Q.top(); Q.pop();
            if(dis[u.m][u.n] < u.val) continue;
            if(pre[u.m][u.n]){
                node h = u; h.n = pre[u.m][u.n]; h.val += b[u.m];
                if(dis[h.m][h.n] > h.val){
                    dis[h.m][h.n] = h.val; Q.push(h);
                }
            }
            if(nxt[u.m][u.n]){
                node h = u; h.n = nxt[u.m][u.n]; h.val += b[u.m];
                if(dis[h.m][h.n] > h.val){
                    dis[h.m][h.n] = h.val; Q.push(h);
                }
            }
            if(u.m){
                node h = u; h.m = 0;
                if(dis[h.m][h.n] > h.val){
                    dis[h.m][h.n] = h.val; Q.push(h);
                }
            }
            if(!u.m){
                for(int i = 0 ; i < P[u.n].size(); i ++){
                    int to = P[u.n][i];
                    node h = u; h.m = to; h.val += a[to];
                    if(dis[h.m][h.n] > h.val){
                        dis[h.m][h.n] = h.val; Q.push(h);
                    }
                }
            }
        }
    }
    int main(){
        scanf("%d%d%d%d",&N,&M,&s,&t);
        for(int i = 1; i <= M ; i ++){
            int k;
            scanf("%d%d%d",&a[i],&b[i],&k);
            for(int j = 1; j <= k ; j ++){
                Sca(tmp[j]); P[tmp[j]].push_back(i);
                nxt[i][tmp[j - 1]] = tmp[j];
                pre[i][tmp[j]] = tmp[j - 1];
            }
        }
        Dijkstra();
        LL ans = 1e18;
        for(int i = 0 ; i <= M ; i ++){
            ans = min(ans,dis[i][t]);
        }
        if(ans == 1e18) ans = -1;
        Prl(ans);
        return 0;
    }
    J
  • 相关阅读:
    Request
    HTTP
    mysql递归查询函数
    redis 6.0.9配置文件详解
    java对数据进行加密、解密
    java Base64编码、解码
    nginx基础使用
    linux指令笔记
    Spring 常用注解粗陋看法
    docker 已有容器修改容器配置
  • 原文地址:https://www.cnblogs.com/Hugh-Locke/p/11178737.html
Copyright © 2020-2023  润新知