답안 #211868

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
211868 2020-03-21T14:39:31 Z nicolaalexandra Traffickers (RMI18_traffickers) C++14
60 / 100
930 ms 524292 KB
/// yay heavy
/// nu mi place acel mle
#include <bits/stdc++.h>
#define DIM 30001
using namespace std;

vector <short> L[DIM],w,aux;
vector <short> chains[DIM];
//short chains[DIM];
long long aib[22][22][DIM];

short whatChain[DIM],positionInChain[DIM],chainFatherNode[DIM],Size[DIM],posAib[DIM];
short E[DIM*3],level[DIM],fth[DIM],first[DIM],p[DIM*3];
pair <short,short> rmq[20][DIM];

int n,m,i,j,x,y,tip,q,k,t1,t2,nr_chains;
long long sum;

void update_aib (int a, int b, int p, int n, int val){
    for (;p<=n;p+=(p&-p))
        aib[a][b][p] += val;
}
long long query_aib (int a, int b, int p){
    if (!p)
        return 0;
    long long sol = 0;
    for (;p;p-=(p&-p))
        sol += aib[a][b][p];
    return sol;
}

long long get_sum (int a, int b, int x, int y){
    return query_aib (a,b,y) - query_aib (a,b,x-1);
}

void dfs (int nod, int tata){
    E[++k] = nod;
    first[nod] = k;
    fth[nod] = tata;
    level[nod] = 1 + level[tata];
    Size[nod] = 1;
    int ok = 0;
    for (auto vecin : L[nod]){
        if (vecin != tata){
            ok = 1;
            dfs (vecin,nod);
            E[++k] = nod;
            Size[nod] += Size[vecin];
        }}

    if (!ok){
        nr_chains++;
        chains[nr_chains].push_back(0);
        chains[nr_chains].push_back(nod);
        //chains[nr_chains] = 1;
        positionInChain[nod] = 1;
        whatChain[nod] = nr_chains;

    } else {

        int maxim = 0, poz = 0;
        for (auto vecin : L[nod]){
            if (vecin == tata)
                continue;
            if (Size[vecin] > maxim)
                maxim = Size[vecin], poz = vecin;
        }

        chains[whatChain[poz]].push_back(nod);
        positionInChain[nod] = chains[whatChain[poz]].size()-1;
        whatChain[nod] = whatChain[poz];

        for (auto vecin : L[nod]){
            if (vecin == tata || vecin == poz)
                continue;
            chainFatherNode[whatChain[vecin]] = nod;
        }}}


int get_lca (int x, int y){
    int posx = first[x], posy = first[y];
    if (posx > posy)
        swap (posx,posy);
    int nr = p[posy - posx + 1];
    pair <int, int> sol = min (rmq[nr][posx], rmq[nr][posy - (1<<nr) + 1]);
    return E[sol.second];
}
void drum (int x, int y){
    int lca = get_lca (x,y);

    w.clear();
    int nod = x;
    while (nod != lca){
        w.push_back(nod);
        nod = fth[nod];
    }
    w.push_back(lca);

    nod = y;
    aux.clear();
    while (nod != lca){
        aux.push_back(nod);
        nod = fth[nod];
    }
    for (j=aux.size()-1;j>=0;j--)
        w.push_back(aux[j]);
}
void adauga (int x, int y){

    drum (x,y);

    /// in w am lantul de la x la y

    int t = 0, lg = w.size();
    for (auto nod : w){

        update_aib(t,lg,posAib[nod],n,1);
        int last = chains[whatChain[nod]][ chains[whatChain[nod]].size()-1 ];
        //update_aib(t,lg,posAib[ last ] + 1,n,-1);

        //update_aib(t,lg,posAib[nod],chains[whatChain[nod]],1);
        t++;
    }
}
void scoate (int x, int y){
    drum (x,y);

    int t = 0, lg = w.size();

    for (auto nod : w){

        update_aib(t,lg,posAib[nod],n,-1);
        //update_aib(t,lg,posAib[ chains[whatChain[nod]][ chains[whatChain[nod]].size()-1 ] ] + 1,n,1);
        //update_aib(t,lg,whatChain[nod],positionInChain[nod],chains[whatChain[nod]],-1);
        t++;
    }
}

void query_heavy (int x, int y, int a, int b){
    if (whatChain[x] == whatChain[y]){
        int posx = positionInChain[x], posy = positionInChain[y];
        if (posx > posy)
            swap (posx, posy), swap (x,y);
        sum += get_sum (a,b,posAib[x],posAib[y]);
        return;
    }
    if (level[chainFatherNode[whatChain[x]]] <= level[chainFatherNode[whatChain[y]]])
        swap (x,y);

    //int posx = positionInChain[x], posy = chains[whatChain[x]];
    sum += get_sum (a,b,posAib[x],posAib[ chains[whatChain[x]][ chains[whatChain[x]].size()-1 ] ]);

    int nr = chainFatherNode[whatChain[x]];
    query_heavy (nr,y,a,b);
}

long long solve (int x, int y, int t){
    if (t < 0)
        return 0;

    long long sol = 0;
    for (int a=0;a<=20;a++){
        if (a > t)
            break;
        for (int b=1;b<=20;b++){
            int nr = (t - a) / b + 1;
            sum = 0;
            query_heavy (x,y,a,b);
            sol += 1LL * nr * sum;
        }
    }

    return sol;
}
int main (){

   // ifstream cin ("traffickers.in");
    //ofstream cout ("traffickers.out");

    cin>>n;
    for (i=1;i<n;i++){
        cin>>x>>y;
        L[x].push_back(y);
        L[y].push_back(x);
    }
    dfs (1,0);

    int idx = 0;

    for (i=1;i<=nr_chains;i++)
        for (j=1;j<chains[i].size();j++){
            int nod = chains[i][j];
            posAib[nod] = ++idx;
        }



    for (i=1;i<=k;i++)
        rmq[0][i] = make_pair(level[E[i]],i);

    for (i=1;(1<<i)<=k;i++)
        for (j=1;j<=k;j++){
            rmq[i][j] = rmq[i-1][j];
            if (j + (1<<(i-1)) <= k && rmq[i-1][j + (1<<(i-1))].first < rmq[i][j].first)
                rmq[i][j] = rmq[i-1][j + (1<<(i-1))];
        }

    for (i=2;i<=k;i++)
        p[i] = p[i/2] + 1;

    cin>>m; /// nr inital de traficanti
    for (i=1;i<=m;i++){
        cin>>x>>y;
        adauga (x,y);
    }

    cin>>q;
    for (;q--;){
        cin>>tip>>x>>y;
        if (tip == 1){
            adauga (x,y);
            continue;
        }
        if (tip == 2){
            scoate (x,y);
            continue;
        }
        cin>>t1>>t2;
        cout<<solve(x,y,t2) - solve(x,y,t1-1)<<"\n";
    }

    return 0;
}

Compilation message

traffickers.cpp: In function 'void adauga(int, int)':
traffickers.cpp:118:13: warning: unused variable 'last' [-Wunused-variable]
         int last = chains[whatChain[nod]][ chains[whatChain[nod]].size()-1 ];
             ^~~~
traffickers.cpp: In function 'int main()':
traffickers.cpp:191:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (j=1;j<chains[i].size();j++){
                  ~^~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 2816 KB Output is correct
2 Correct 13 ms 4608 KB Output is correct
3 Correct 14 ms 4352 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 403 ms 19704 KB Output is correct
2 Correct 504 ms 16516 KB Output is correct
3 Correct 304 ms 20984 KB Output is correct
4 Correct 428 ms 19504 KB Output is correct
5 Correct 496 ms 18552 KB Output is correct
6 Correct 417 ms 19192 KB Output is correct
7 Correct 420 ms 19832 KB Output is correct
8 Correct 382 ms 21752 KB Output is correct
9 Correct 437 ms 22136 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Runtime error 900 ms 524292 KB Execution killed with signal 9 (could be triggered by violating memory limits)
2 Runtime error 905 ms 524288 KB Execution killed with signal 9 (could be triggered by violating memory limits)
3 Runtime error 892 ms 524292 KB Execution killed with signal 9 (could be triggered by violating memory limits)
4 Runtime error 930 ms 524292 KB Execution killed with signal 9 (could be triggered by violating memory limits)
5 Runtime error 894 ms 524292 KB Execution killed with signal 9 (could be triggered by violating memory limits)
6 Runtime error 912 ms 524288 KB Execution killed with signal 9 (could be triggered by violating memory limits)
7 Runtime error 904 ms 524288 KB Execution killed with signal 9 (could be triggered by violating memory limits)
8 Runtime error 60 ms 16376 KB Execution killed with signal 11 (could be triggered by violating memory limits)