95 分,来回Wa,求助。
查看原帖
95 分,来回Wa,求助。
203453
Foofish楼主2022/9/3 15:54

如果 cyc 那里定义成

vector<long long>cyc;

会Wa 16 号点

如果改成

vector<int>cyc;

会Wa 11 号点

太怪了,有大佬能帮忙看看么?

#include <bits/stdc++.h>
using namespace std;
template <typename T>inline void read(T& t){t=0; register char ch=getchar(); register int fflag=1;while(!('0'<=ch&&ch<='9')) {if(ch=='-') fflag=-1;ch=getchar();}while(('0'<=ch&&ch<='9')){t=t*10+ch-'0'; ch=getchar();} t*=fflag;}
template <typename T,typename... Args> inline void read(T& t, Args&... args) {read(t);read(args...);}
const int N = 6e6 + 10;

int n, fa[N];
long long dp[N], va[N], maxx, s[N];
bool vis[N], oncyc[N];
vector<pair<int, long long> >G[N];

void dfs(int u){ //树形dp
    vis[u] = 1;
    for(auto [v,val]:G[u]){
        if(oncyc[v]) continue;
        dfs(v);
        maxx = max(maxx, dp[u] + dp[v] + val); 
        dp[u] = max(dp[u], dp[v] + val);
    }
}

long long ans;

int main() {
    read(n);
    for(int i = 1; i <= n; ++i) {
        int x;
        long long val;
        read(x, val);
        fa[i] = x;
        va[i] = val;
        G[x].push_back(make_pair(i, val));
    }
    for(int i = 1; i <= n; ++i) if(!vis[i]) {
        vector<int>cyc;
        cyc.clear();
        int u = i;
        while(!vis[u]){
            vis[u] = 1;
            u = fa[u];
        }
        int v = u;
        while(1){
            cyc.push_back(v);
            oncyc[v] = 1;
            v = fa[v];
            if(v == u) break;
        }
        maxx = 0;
        for(int id:cyc) dfs(id);
        // 环上 dp
        int m = cyc.size();
        for(int i = 0; i < m; ++i) cyc.push_back(cyc[i]); //复制一圈
        deque<pair<int,long long> >Q; //单调队列
        while(!Q.empty()) Q.pop_back();
        s[0] = 0;
        for(int i = 1; i < cyc.size(); ++i) s[i] = s[i - 1] + va[cyc[i - 1]]; //计算距离
        for(int i = 0; i < cyc.size(); ++i){
            while(!Q.empty() && Q.front().first <= i - m) Q.pop_front();
            maxx = max(maxx, Q.front().second + dp[cyc[i]] + s[i]);
            while(!Q.empty() && Q.back().second <= dp[cyc[i]] - s[i]) Q.pop_back();
            Q.push_back(make_pair(i, dp[cyc[i]] - s[i]));
        }
        ans += maxx;
    }
    cout << ans << endl;
    return 0;
}

2022/9/3 15:54
加载中...