i题

思路:多次dj求解即可

#include <bits/stdc++.h>
using namespace std;
#define int long long
int inf = 1e13;
signed main(){
    int n, m, k;
    cin >> n >> m >> k;
    vector<array<int,3>>g[n + 1];
    for(int i = 1; i <= m; i++){
        int a,b,c,d;
        cin >> a>>b >> c>> d;
        g[a].push_back({b,c,d});
        g[b].push_back({a,c,d});
    }
    function<int(int,int,int)> get = [&](int s,int e,int f){
        vector<int>vis(n + 1);
        vector<int>dis(n + 1, inf);
        dis[s] = 0;
        priority_queue<pair<int,int>>q;
        q.push({0, s});
        while(q.size()){
            auto [ds, id] = q.top();q.pop();
            ds = -ds;
            if(vis[id])continue;
            vis[id] = 1;
            for(auto [b,c,d]: g[id]){
                if(f){ // 有钥匙
                    if(dis[b] > c + ds){
                        dis[b] = c + ds;
                        q.push({-dis[b], b});
                    }
                }
                else{
                    if(d == 0)continue;
                    else{
                        if(dis[b] > c + ds){
                            dis[b] = c + ds;
                            q.push({-dis[b], b});
                        }
                    }
                }
            }
        }
        return dis[e];
    };
    
    int dis1 = get(1, k, 0);
    if(dis1 != inf){
        int dis2 = get(k, n, 1);
        int ans = get(1, n, 0);
        cout << min(ans, dis1 + dis2) <<endl;
    }
    else{
        int ans = get(1, n, 0);
        cout << (ans == inf ? -1 : ans) << endl;
    }
    
    return 0;
}

e题

思路:暴力分块

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const int M = 1010;
int a[N];
int be[N],L[M],R[M];
int tag[M];
int tagl[M],tagr[M];

void cg(int k){ // cg是维护的块的信息
    int mx = 0, cnt = 0;
    tagl[k] = -1;
    tagr[k] = -1;

    for(int i = L[k]; i <= R[k]; i++){
        if(a[i])cnt ++;
        else {
            if(tagl[k] == -1)tagl[k] = cnt;
            
            mx = max(mx, cnt);
            cnt = 0;
        }
    }
    if(tagl[k] == -1)tagl[k] = cnt;
    tagr[k] = cnt;
    mx = max(mx, cnt);
    tag[k] = mx;
}

signed main(){
    int n, q;
    cin >> n >> q;
    for(int i = 1; i <= n; i++) a[i] = 1;
    int b = sqrt(n);
    int ct = (n + b - 1) / b;
    for(int i = 1; i <= ct; i++){
        L[i] = (i - 1) * b + 1;
        R[i] = min(n, i * b);
        for(int j = L[i]; j <= R[i]; j++){
            be[j] = i;
        }
        cg(i);
    }
    while(q--){
        int op;
        cin >> op;
        if(op == 1){
            int x; cin >> x;
            a[x] ^= 1;
            cg(be[x]);
        }
        else if(op == 2){
            int l, r;cin >> l >> r;
            if(be[l] == be[r]){
                int mx = 0, cnt = 0;
                for(int i = l; i <= r; i++){
                    if(a[i])cnt ++;
                    else {
                        mx = max(mx, cnt);
                        cnt = 0;
                    }
                }
                mx = max(mx, cnt);
                cout << mx << endl;
            }
            else{
                int mx = 0, cnt = 0;
                for(int i = l; i <= R[be[l]]; i++){
                    if(a[i])cnt ++;
                    else {
                        mx = max(mx, cnt);
                        cnt =  0;
                    }
                }
                mx = max(mx, cnt);
                int per = cnt;
                
                int bkl = -1;
                cnt = 0;
                for(int i = L[be[r]]; i <= r; i++){
                    if (a[i])cnt++;
                    else{
                        if(bkl == -1)bkl = cnt;
                        mx = max(mx, cnt);
                        cnt = 0;
                    }
                }
                if(bkl == -1)bkl = cnt;
                mx = max(mx, cnt);
                // ct 个
                cnt = per;
                for(int k = be[l] + 1; k <= be[r] - 1; k++){
                    mx = max(mx, tag[k]);
                    if(tag[k] == R[k] - L[k] + 1){
                        cnt += R[k] - L[k] + 1;
                    }
                    else{
                        cnt += tagl[k];
                        mx = max(mx, cnt);
                        cnt = tagr[k];
                    }
                }
                mx = max(mx, cnt + bkl);
                cout << mx << endl;
            }
            
        }
        // for(int i = 1; i <= ct; i++){
        //     cout << "第"<< i <<"个块:" << tag[i] <<' ' << tagl[i] <<' ' << tagr[i] << endl;
        // }

    }

    return 0;
}