• HZNU第十二届校赛赛后补题


    愉快的校赛翻皮水!

    题解

    A 温暖的签到,注意用gets

    #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 = 1000000 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,K;
    string a; 
    int main(){
        while(getline(cin,a)){
            a.back() = '!';
            cout << a << endl;
        }
        return 0;
    }
    A

    B.比赛的时候一直以为是主席树上操作或者其他的高级数据结构,万万没想到是在序列特性下手,打一张最小的不冲突的表就会发现斐波那契数列是最小不冲突序列,int范围内最多容纳47个数左右,所以小于50的范围暴力查询,大于50的范围必定YES

    #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 = 2e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,K;
    LL a[maxn];
    LL b[maxn];
    int main(){
        Sca2(N,M);
        for(int i = 1; i <= N ; i ++) Scl(a[i]);
        for(int i = 1; i <= M ; i ++){
            int l,r; Sca2(l,r);
            if(r - l + 1 < 3){
                puts("NO");
                continue;
            }
            if(r - l + 1 >= 50) puts("YES");
            else{
                int flag = 0;
                for(int j = l; j <= r; j ++) b[j] = a[j];
                sort(b + l,b + r + 1);
                for(int j = l + 2; j <= r; j ++){
                    if(b[j - 2] + b[j - 1] > b[j]){
                        flag = 1;
                        break;
                    }
                }
                if(flag) puts("YES");
                else puts("NO");
            }
        }
        return 0; //1 1 2 3 5 8 13 21 34
    }
    B

    D. 8说了,温暖的签到

    #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 = 2e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,K;
    int a[maxn];
    set<int>Q;
    int main(){
        N = read();
        while(N--) Q.insert(read());
        Pri(Q.size());
        return 0; //1 1 2 3 5 8 13 21 34
    }
    D

    E.给一个条件构造的图,求图上的哈密顿回路。

    可以猜想到N为奇数的时候始终不可行。

    N为偶数的时候必定可行,并且可以发现,每个点都恰好有两个出度和两个入度,

    这就可以转换成欧拉回路直接做

    #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;
    int ans[maxn],cnt;
    bool vis[maxn];
    void dfs(int t){
        int l = (t * 2) % N,r = (t * 2 + 1) % N;
        if(l > r) swap(l,r);
        if(!vis[r]){vis[r] = 1;dfs(r);}
        if(!vis[l]){vis[l] = 1;dfs(l);}
        ans[++cnt] = t;
    }
    int main(){
        Sca(N);
        if(N & 1){puts("-1"); return 0;}
        dfs(0);
        for(int i = cnt ; i >= 1; i --)cout << ans[i] << " " ;
        return 0;
    }
    E

    G.由于每天加的钱为实数而不要求为浮点数,一个显然的贪心是每两个取的物品i,j之间,每天加入的钱都是wj / (j - i)

    dp是显然的,第一个难点在于每天钱数不增的限制,如果dp存储加入的钱数,2000 * 1e6很显然时间复杂度上过不去

    一个比较巧妙地思想是dp[i][j]表示上一个操作是i - > j的物品的选择,2000 * 2000满足了时间复杂度还满足了钱数

    得到状态转移方程dp[j][k] = max(dp[i][j] + V[k])

    到了这一步就可以写出一个n3 的暴力(雾),将状态转移方程变形,得到i > j - W(j) / W(k) * (k - j)这样一个右边和i无关的方程.

    所以考虑枚举j和k,然后就可以得到i的下界,i的上界显然为j - 1,就变成了一个后缀最大值的问题,这个甚至不需要树状数组,直接维护一个简单的一维数组即可.

    时间复杂度n²

    #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-6;
    const int maxn = 2010;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N;
    struct Good{
        LL v;
        double w;
    }P[maxn];
    LL dp[maxn][maxn];
    LL Max[maxn];
    int main(){
        Sca(N);
        for(int i = 1; i <= N ; i ++) scanf("%lf",&P[i].w);
        for(int i = 1; i <= N ; i ++) Scl(P[i].v);
        for(int i = 0; i <= N ; i ++){
            for(int j = 0; j <= N ; j ++){
                dp[i][j] = -1e18;
            }
        }
        for(int i = 1; i <= N ; i ++) dp[0][i] = P[i].v;
        for(int j = 1; j <= N ; j ++){
            Max[j] = -1e18;
            for(int k = j - 1; k >= 0; k --) Max[k] = max(Max[k + 1],dp[k][j]);
            for(int k = j + 1; k <= N ; k ++){
                double l;
                if(!P[k].w) l = 0;
                else l = max(j - P[j].w / P[k].w * (k - j),(double)0);
                int L = (int)l;
                if(fabs(l - L) > eps) L++;
                if(L > j - 1) continue;
                dp[j][k] = Max[L] + P[k].v; // Max[k][j]
            }
        }
        LL ans = 0;
        for(int i = 0; i <= N ; i ++){
            for(int j = i + 1; j <= N ; j ++){
                ans = max(ans,dp[i][j]);
            }
        }
        Prl(ans);
        return 0;
    }
    G

    H.取个log就会发现变成AjlogAi > AilogAj,直接sort一波,特判一下前后相等的情况即可.

    #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;
    PIL a[maxn];
    int ans[maxn];
    bool cmp(PIL x,PIL y){
        return 1.0 * x.se * log(y.se * 1.0) > 1.0 * y.se * log(x.se * 1.0);
    }
    bool equal(double x,double y){
        return fabs(x - y) < eps;
    }
    int main(){
        N = read();
        for(int i = 1; i <= N ; i ++){
            Scl(a[i].se);
            a[i].fi = i;
        } 
        sort(a + 1,a + 1 + N,cmp);
        int cnt = 0;
        for(int i = 1; i <= N ; i ++){
            if(i > 1 && equal(1.0 * a[i].se * log(a[i - 1].se * 1.0),1.0 * a[i - 1].se * log(a[i].se * 1.0))) cnt++;
            else cnt = 0;
            ans[a[i].fi] = i - 1 - cnt;
        }
        for(int i = 1; i <= N ; i ++){
            printf("%d ",ans[i]);
        }
        return 0;
    }
    H

    I.要有多坑有多坑,正确题意为双射 + 最后25字母可推26字母,其他没有难度

    #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 = 1e6 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,K;
    int to[30],to2[30];
    char str[maxn],str2[maxn];
    int main(){
        while(~scanf("%s%s",str,str2)){
            int l = strlen(str);
            for(int i = 0 ; i < 26; i ++) to[i] = to2[i] = -1;
            for(int i = 0; str[i]; i ++){
                int id1 = str[i] - 'a',id2 = str2[i] - 'a';
                if(~to[id1] && to[id1] != id2){
                    puts("Impossible"); exit(0);
                }
                if(~to2[id2] && to2[id2] != id1){
                    puts("Impossible"); exit(0);
                }
                to[id1] = id2; to2[id2] = id1;
            }
            int cnt = 0;
            for(int i = 0 ; i < 26; i ++) if(~to[i]) cnt++;
            if(cnt == 25){
                int t = 0;
                for(int i = 0 ; i < 26; i ++){
                    if(to[i] == -1) t = i;
                }
                for(int i = 0 ; i < 26; i ++) if(to2[i] == -1) to[t] = i;
            }
            for(int i = 0 ; i < 26; i ++){
                if(~to[i]) printf("%c->%c
    ",i + 'a',to[i] + 'a');
            }
        }
        return 0;
    }
    I

    J.过于温暖,给出题人点赞

    #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 N,M,K,T;
    int main(){
        cin >> N >> K >> T;
        cout << max(0LL,N - K * T) << endl;
        return 0;
    }
    J

    K.很显然是预处理出所有情况然后二分端点.

    坑点1.不能用海伦公式,过不了double浮点数的误差,需要用向量叉积并且不除2,后面查询的时候将l和r乘2达到无浮点数的目的

    2.r用upper_bound,l用lower_bound,最后r - l即可,天知道为什么我一开始手写了两个二分

    #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 = 310;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,Q;
    struct Point{
        LL x,y;
    }point[maxn];
    LL P[255 * 255 * 50];
    LL cul(LL x1,LL y1,LL x2,LL y2){
        //cout << x1 << " " << y1 << " " << x2 << " " << y2 << endl;
        return abs(x1 * y2 - x2 * y1);
    }
    int main(){
        Sca2(N,Q);  //x1:(ax - bx) y1:(ay - by) x2:ax - cx y2:ay - cy
        for(int i = 1; i <= N ; i ++) scanf("%lld%lld",&point[i].x,&point[i].y);
        int cnt = 0;
        for(int i = 1; i <= N ; i ++){
            for(int j = i + 1; j <= N; j ++){
                LL x1 = point[i].x - point[j].x,y1 = point[i].y - point[j].y;
                for(int k = j + 1; k <= N ; k ++){
                    LL x2 = point[i].x - point[k].x,y2 = point[i].y - point[k].y;
                    P[++cnt] = cul(x1,y1,x2,y2);
                }
            }
        }
        sort(P + 1,P + 1 + cnt);
        //for(int i = 1; i <= cnt; i ++) cout << P[i] << " ";
        //cout << endl;
        for(int i = 1; i <= Q; i ++){
            LL l,r; scanf("%lld%lld",&l,&r);
            l *= 2; r *= 2;
            l = lower_bound(P + 1,P + 1 + cnt,l) - P;
            r = upper_bound(P + 1,P + 1 + cnt,r) - P;
            //cout << l << ' ' << r << endl;
            Pri(r - l);
        }
        return 0;
    }
    K

    L.考虑从T开始跑一颗最短路树,那么如果当人在i点的时候去掉边,显然去掉非树边上的边的行为是无意义的,如果去掉了树边上的边,那么就需要走到他们的子树上某个结点j,通过一个非树边走到一个非子树的结点k,然后再到T点,距离就是dis[j] - dis[i] + edge(j,k) + dis[k]

    显然(雾)我们可以对每一条非树边进行预处理,每一条连接(i,j)的非树边将会对i到lca(i,j),j到lca(i,j)的两条链产生贡献(目的是寻找一条i点树边被封之后最短的走到T的路线),这个过程可以用树链剖分实现

    最后再从T开始往S跑最短路,由于我们已经求出了每个点i的树边被封之后到T的最短路,所以更新答案是dis[v] = max(dis[u.pos] + edge[i].dis,dis2[v]);

    也就是说,如果在v点直接切断会比在之后切断造成需要走更长的路。

    #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 = 2e5 + 10;
    const int maxm = 2e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,S,T;
    struct Edge{
        int to,next;
        LL dis;
    }edge[maxm * 2];
    struct E{
        int u,v,flag;
        LL w;
        E(){}
        E(int u,int v,LL w):u(u),v(v),w(w){}
    }e[maxm * 2];
    int head[maxn],tot; 
    void init(){
        for(int i = 0 ; i <= N ; i ++) head[i] = -1;
        tot = 0;
    }
    void add(int u,int v,LL w){
        edge[tot].to = v;
        edge[tot].next = head[u];
        edge[tot].dis = w;
        head[u] = tot++;
    }
    struct node{
        int pos;
        LL cost;
        node(){}
        node(int pos,LL cost):pos(pos),cost(cost){}
        friend bool operator < (node a,node b){
            return a.cost > b.cost;
        }
    };
    LL dis[maxn],dis2[maxn];
    int fa[maxn];
    void Dijkstra(int s){
        for(int i = 1; i <= N ; i ++) dis[i] = 1e18;
        priority_queue<node>Q;
        Q.push(node(s,0)); fa[s] = dis[s] = 0;
        while(!Q.empty()){
            node u = Q.top(); Q.pop();
            if(u.cost > dis[u.pos]) continue; 
            for(int i = head[u.pos]; ~i; i = edge[i].next){
                int v = edge[i].to;
                if(dis[v] > dis[u.pos] + edge[i].dis){
                    dis[v] = dis[u.pos] + edge[i].dis;
                    fa[v] = u.pos;
                    Q.push(node(v,dis[v]));
                }
            }
        }
    }
    int dep[maxn],top[maxn],pos[maxn],size[maxn],son[maxn];
    void dfs1(int t,int la){
        size[t] = 1; son[t] = t;
        int heavy = 0;
        for(int i = head[t]; ~i ; i = edge[i].next){
            int v = edge[i].to;
            if(v == la) continue;
            dep[v] = dep[t] + 1;
            fa[v] = t;
            dfs1(v,t);
            if(size[v] > heavy){
                heavy = size[v];
                son[t] = v;
            }
            size[t] += size[v];
        }
    }
    int cnt;
    void dfs2(int t,int la){
        top[t] = la;
        pos[t] = ++cnt;
        if(son[t] == t) return;
        dfs2(son[t],la);
        for(int i = head[t]; ~i ; i = edge[i].next){
            int v = edge[i].to;
            if((fa[t] == v) || v == son[t]) continue;
            dfs2(v,v);
        }
    }
    int lca(int u,int v){
        while(top[u] != top[v]){
            if(dep[top[u]] < dep[top[v]]) swap(u,v);
            u = fa[top[u]];
        }
        if(dep[u] < dep[v]) return u;
        return v;
    }
    struct Tree{
        int l,r;
        LL lazy;
    }tree[maxn << 2];
    void Build(int t,int l,int r){
        tree[t].l = l; tree[t].r = r;
        tree[t].lazy = 1e18;
        if(l == r) return;
        int m = l + r >> 1;
        Build(t << 1,l,m); Build(t << 1 | 1,m + 1,r);
    }
    void Pushdown(int t){
        tree[t << 1].lazy = min(tree[t << 1].lazy,tree[t].lazy);
        tree[t << 1 | 1].lazy = min(tree[t << 1 | 1].lazy,tree[t].lazy);
    }
    void update(int t,int l,int r,LL sum){
        if(l <= tree[t].l && tree[t].r <= r){
            tree[t].lazy = min(tree[t].lazy,sum);
            return ;
        }
        Pushdown(t);
        int m = tree[t].l + tree[t].r >> 1;
        if(r <= m) update(t << 1,l,r,sum);
        else if(l > m) update(t << 1 | 1,l,r,sum);
        else{
            update(t << 1,l,m,sum);
            update(t << 1 | 1,m + 1,r,sum);
        }
    }
    LL query(int t,int p){
        if(tree[t].l == tree[t].r) return tree[t].lazy; 
        Pushdown(t);
        int m = tree[t].l + tree[t].r >> 1;
        if(p <= m) return query(t << 1,p);
        else return query(t << 1 | 1,p);
    }
    void update(int u,int v,LL sum){
        while(top[u] != top[v]){
            update(1,pos[top[u]],pos[u],sum);
            u = fa[top[u]];
        }
        if(u == v) return;
        update(1,pos[v] + 1,pos[u],sum);
    }
    int main(){
        scanf("%d%d%d%d",&N,&M,&S,&T); init();
        for(int i = 1; i <= M ; i ++){
            int u,v; Sca2(u,v); LL w; Scl(w);
            add(u,v,w); add(v,u,w);
            e[i] = E(u,v,w); e[i].flag = 1;
        }
        Dijkstra(T); init();
        for(int i = 1; i <= M ; i ++){
            if(fa[e[i].u] == e[i].v || fa[e[i].v] == e[i].u){
                add(e[i].v,e[i].u,e[i].w);
                add(e[i].u,e[i].v,e[i].w);
            }else e[i].flag = 0;
        }
        dfs1(T,T); dfs2(T,T);
        Build(1,1,N);
        for(int i = 1; i <= M ; i ++){
            if(e[i].flag) continue;
            LL sum = dis[e[i].u] + dis[e[i].v] + e[i].w;
            int l = lca(e[i].u,e[i].v);
            update(e[i].u,l,sum); update(e[i].v,l,sum);
        }
        for(int i = 1; i <= N; i ++) dis2[i] = query(1,pos[i]) - dis[i];
        for(int i = 1; i <= N ; i ++) dis[i] = 1e18;  init();
        for(int i = 1; i <= M ; i ++){
            add(e[i].u,e[i].v,e[i].w);
            add(e[i].v,e[i].u,e[i].w);
        } 
        priority_queue<node>Q;
        Q.push(node(T,0)); dis[T] = 0;
        while(!Q.empty()){
            node u = Q.top(); Q.pop();
            if(dis[u.pos] < u.cost) continue;
            for(int i = head[u.pos]; ~i ; i = edge[i].next){
                int v = edge[i].to;
                if(dis[v] > max(dis[u.pos] + edge[i].dis,dis2[v])){
                    dis[v] = max(dis[u.pos] + edge[i].dis,dis2[v]);
                    Q.push(node(v,dis[v]));
                }
            }
        }
        if(dis[S] >= 1e16) puts("-1");
        else Prl(dis[S]);
        return 0;
    }
    L

    M.用SG函数打表博弈,反正我是不会做,贴上队友代码

    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <stdlib.h>
    #include <map>
    #include <set>
    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <vector>
    #include <queue>
    
    
    using namespace std;
    
    typedef long long LL;
    const int maxn = 1e6+500;
    int if_pre[maxn +5];
    
    void pre_first()
    {
        memset(if_pre, 0x3f, sizeof(if_pre));
        if_pre[0] = 0;
        if_pre[1] = 1;
        int pre_num =2;
        for (int i = 2; i < maxn; i++)
        {
            if (if_pre[i] == 0x3f3f3f3f)
            {
                if_pre[i] = pre_num++;
                for (int j = i << 1; j < maxn; j += i)
                {
                    if_pre[j] = min(if_pre[j],if_pre[i]);
                }
            }
        }
    }
    
    int main()
    {
        int t;
        cin >>t;
        pre_first();
        while (t --)
        {
            int n,a;
            cin >>n;
            int sum =0;
            while (n--)
            {
                cin >>a;
                sum^=if_pre[a];
                //cout<<a<<'*'<<if_pre[a]<<endl;
            }
            if (sum)
                cout<<"Subconscious is our king!"<<endl;
            else
                cout<<"Long live with King Johann!"<<endl;
            
        }
    
    
    
    
    #ifdef VSCode
        system("pause");
    #endif
        return 0;
    }
    M
  • 相关阅读:
    深入理解JavaScript系列(4):立即调用的函数表达式
    深入理解JavaScript系列(3):全面解析Module模式
    深入理解JavaScript系列(2):揭秘命名函数表达式
    深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点
    深入理解JavaScript系列
    大白话讲解Promise(一)
    《你不知道的JavaScript》整理(二)——this
    Mysql日期时间大全
    Mysql的时间和日期
    mysql命令大全用户管理相关命令
  • 原文地址:https://www.cnblogs.com/Hugh-Locke/p/10556118.html
Copyright © 2020-2023  润新知