QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#862893#9732. Gathering MushroomsZawosWA 51ms5860kbC++207.0kb2025-01-19 10:41:552025-01-19 10:41:56

Judging History

你现在查看的是最新测评结果

  • [2025-01-19 10:41:56]
  • 评测
  • 测评结果:WA
  • 用时:51ms
  • 内存:5860kb
  • [2025-01-19 10:41:55]
  • 提交

answer

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define FOR(i,a,b) for (int i = (a); i < (b); i++)
using namespace std;
using namespace __gnu_pbds;
using ll=long long;
using ld=long double;
using vi=vector<int>;
template<class T> using oset =tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update> ;
//上

const int N = 200005;
const ll inf = 1000000000000000000;
int par[N][20];
int par1[N][20];
ll k;
map<ll,ll>mp;
void init_par(vector<int> &parent){
    int n = parent.size();
    for(int i = 0; i < n;i++){
        if(parent[i] == -1) par[i][0] = i;
        else par[i][0] = parent[i];
    }
    for(int i = 1; i < 20; i++){
        for(int j = 0; j < n; j++) par[j][i] = par[par[j][i-1]][i-1];
    }
}
void init_par2(vector<int> &parent){
    int n = parent.size();
    for(int i = 0; i < n;i++){
            par1[i][0] = parent[i];
    }
    for(int i = 1; i < 20; i++){
        for(int j = 0; j < n; j++) if(parent[j] != -1) par1[j][i] = par1[par1[j][i-1]][i-1];
    }
}
ll jump(int x,int y){
    ll su = 1;
    for(int i = 19; i>= 0;i--){
        if(par[x][i] != y&&par[x][y] != x) x = par[x][i],su +=(1<<i);
    }
    return su;
}
int move(int x,ll dis){
    for(int i = 0; i < 20 ; i++){
        if(dis&(1<<i)) x = par[x][i];
    }
    return x;
}
int move2(int x,ll dis){
    for(int i = 0; i < 20 ; i++){
        if(dis&(1<<i)) x = par1[x][i];
    }
    return x;
}
void toposort(int x,vector<vector<int>> &AL,vector<int>&vis,vector<int> &topo){
    vis[x] = 1;
    for(auto &u: AL[x]){
        if(vis[u] == 0) toposort(u,AL,vis,topo);
    }
    topo.push_back(x);
}
void dfs(int x,int c,vector<vector<int>> &AL,vector<int> &scc){
    scc[x] = c;
    for(auto &u: AL[x]){
        if(scc[u] == -1) dfs(u,c,AL,scc);
    }
}
void create_ancester_tree(int x,int root,vector<int> &v,vector<vector<int>> &nAL,vector<int> & parent,vector<int> &last,vector<int>&depth){
    if(x != root){
        if(last[v[x]] != -1) parent[x] = last[v[x]];
        else parent[x] = root;
        last[v[x]] = x;
    }
    for(auto &u: nAL[x]){
        depth[u] = depth[x] + 1;
        create_ancester_tree(u,root,v,nAL,parent,last,depth);
    }
    if(x!=root) last[v[x]] = parent[x];
}

vector<ll> calc_cycle(int x,vector<vector<int>> &AL,vector<int> &v,vector<ll> &ans,vector<ll> &distance,vector<int>&position,vector<int>&last,vector<int>&parent){
    ll sz = 1;
    int p1 = x;
    int p2 = x;
    map<int,ll> val;
    ll mx = 1;
    val[v[x]]++;
    position[p1] = sz-1;
    last[v[p1]] = -1;
    vector<ll> cyc = {x};
    while(AL[p1][0] != x){
        p1 =AL[p1][0],sz++;
        position[p1] = sz-1;
        last[v[p1]] = -1;
        cyc.push_back(p1);
        mx = max(mx,++val[v[p1]]);
    }
    ll vueltas = ((k+mx-1)/mx-1);
    for(auto &u:val){
        u.second = u.second*vueltas;
    }

    p1 = x;
    ll d = 0;
    val[v[p1]]++;
    for(int i = 0; i < sz;i++){
        while(true){
            if(val[v[p2]] == k){
                distance[p1] = vueltas*sz+d;
                ans[p1] = v[p2];
                break;
            }else{
                p2 = AL[p2][0];
                val[v[p2]]++;
                d++;
            }
        }
        d--;
        val[v[p1]]--;
        p1 = AL[p1][0];
    }
    p1 = x;
    for(int i = 0; i <2*sz;i++){
        if(last[v[p1]] != -1){
            parent[last[v[p1]]] = p1;
        }
        last[v[p1]] = p1;
        p1 = AL[p1][0];
    }
    return cyc;
}
void calc_tree(int x,int root,ll sz,vector<vector<int>> &AL,vector<int> &v,vector<ll> & ans,vector<ll> &distance,vector<int> &last,vector<int>&depth,vector<int>&position){
    for(auto &u: AL[x]){
        ll steps = 0;
        ll su = 0;
        ll toroot = jump(u,root);
        if(toroot >= k){
            su = depth[u]-depth[move(u,k-1)];
        }else{
            if(last[v[u]] !=-1){
                steps = toroot;
                su = depth[u];
                if(position[last[v[u]]] >= position[root]){
                    su +=position[last[v[u]]] -position[root];
                }else{
                    su += sz-position[root]+position[last[v[u]]];
                }
                
                ll many = mp[v[u]];
                ll o = (k-steps +many-1)/many-1;
                steps += o* many;
                su+=o*sz;
                ll extra =move2(position[last[v[u]]],k-steps-1);
                if(extra >= position[last[v[u]]]){
                    su += extra-position[last[v[u]]];
                }else su += sz-position[last[v[u]]]+extra;
            }else su = inf;
        }
            if(su <distance[x] +1){
                distance[u] = su;
                ans[u] = v[u];
            }else{
                distance[u] = distance[x]+1;
                ans[u] = ans[x];
            }
        calc_tree(u,root,sz,AL,v,ans,distance,last,depth,position);
    }
}
int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    // freopen("18.01.2025\\input.txt","r",stdin);
    // freopen("18.01.2025\\output.txt","w",stdout);
    int t;
    cin >> t;
    while(t--){
        ll n; cin >> n >> k;
        vector<vector<int>> AL(n),AL_T(n);
        vector<int> v(n),scc(n,-1),vis(n),parent(n,-1),last(n,-1),depth(n),position(n),aux(n,-1);
        vector<ll> ans(n,-1),distance(n);

        vector<int>topo;
        FOR(i,0,n){cin >> v[i];v[i]--;}
        FOR(i,0,n){
            int x; cin >> x;
            x--; AL[i].push_back(x); AL_T[x].push_back(i);
        }
        for(int i = 0; i < n; i++){
            if(!vis[i]) toposort(i,AL,vis,topo);
        }
        reverse(topo.begin(),topo.end());
        int cur = 0;
        for(auto &u: topo){
            if(scc[u] == -1) dfs(u,cur++,AL_T,scc);
        }
        vector<vector<int>> nAL(n);
        for(int i = 0; i < n; i++){
            if(scc[AL[i][0]] != scc[i]) nAL[AL[i][0]].push_back(i);
        }

        for(int i = 0; i < n; i++){
            if(scc[AL[i][0]] == scc[i]) create_ancester_tree(i,i,v,nAL,parent,last,depth);
        }
        init_par(parent);
        for(int i = 0; i < n; i++) parent[i] = -1;
        vector<vector<ll>> temp;
        for(int i = 0; i < n; i++){
            if(scc[AL[i][0]] == scc[i] && ans[i] == -1){
                temp.push_back(calc_cycle(i,AL,v,ans,distance,position,last,parent));
            }
        }
        init_par2(parent);

        for(int i = 0; i < n; i++) last[i] = -1;
        for(auto &u: temp){
            mp.clear();
            for(int i = (int)u.size()-1; i >= 0;i--){
                last[v[u[i]]] = u[i];
                mp[v[u[i]]]++;
            }
            for(int i = (int)u.size()-1; i >= 0;i--){
                calc_tree(u[i],u[i],u.size(),nAL,v,ans,distance,last,depth,position);
                last[v[u[i]]] = u[i];
            }
            for(int i = 0; i < u.size();i++) last[v[u[i]]] = -1;
        }
        ll re = 0;
        for(ll i = 1; i <= n;i++) re += i*(ans[i-1]+1);
        cout <<re<<'\n';
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 5860kb

input:

3
5 3
2 2 1 3 3
2 5 1 2 4
5 4
2 2 1 3 3
2 5 1 2 4
3 10
1 2 3
1 3 2

output:

41
45
14

result:

ok 3 lines

Test #2:

score: -100
Wrong Answer
time: 51ms
memory: 5692kb

input:

6000
19 48
18 19 18 19 11 9 15 19 12 18 11 18 9 18 9 18 19 11 15
12 14 18 8 1 3 19 5 13 14 15 2 14 5 19 2 19 12 9
15 23
3 1 1 3 6 1 4 1 1 6 6 4 12 4 6
14 1 8 8 6 6 12 14 6 8 5 7 14 2 5
9 140979583
4 5 8 9 2 7 6 8 2
8 9 4 6 9 2 4 7 8
4 976357580
2 3 1 3
2 1 1 4
6 508962809
4 3 4 3 4 4
4 5 4 5 5 6
13 ...

output:

2601
260
254
26
84
743
126
30
1092
1
2367
2422
168
360
338
324
2424
2520
220
228
1104
9
3486
1
796
81
340
272
600
2566
32
495
40
128
140
665
1502
702
68
96
90
288
29
561
16
234
445
3114
140
40
477
1237
19
1994
1082
32
613
672
20
390
32
2204
1942
42
21
885
4
855
196
420
11
1408
793
720
1
556
40
17
21...

result:

wrong answer 1st lines differ - expected: '3420', found: '2601'