Submission #212196

# Submission time Handle Problem Language Result Execution time Memory
212196 2020-03-22T13:08:41 Z Ruxandra985 Traffickers (RMI18_traffickers) C++14
60 / 100
3500 ms 524292 KB
#include <bits/stdc++.h>
#define DIMN 100010
using namespace std;
int tt[DIMN] , lvl[DIMN] , f[DIMN];
int up[DIMN] , l[DIMN] , d[DIMN] , poz[DIMN] , idx_aint[DIMN];
vector < map <int,int> > aint[DIMN];
vector <int> v[DIMN] , w[DIMN];
char buff[5000];
int elem , lnt , pos;
int getnr(){
    int nr = 0;

    while ('0' > buff[pos] || buff[pos] > '9'){
        pos++;
        if (pos == 5000){
            fread (buff , 1 , 5000 , stdin);
            pos = 0;
        }
    }

    while ('0' <= buff[pos] && buff[pos] <= '9'){
        nr = nr * 10 + buff[pos] - '0';
        pos++;
        if (pos == 5000){
            fread (buff , 1 , 5000 , stdin);
            pos = 0;
        }
    }


    return nr;
}
void dfs (int nod , int fth , int nivel){
    int i , vecin;

    tt[nod] = fth;
    lvl[nod] = nivel;
    d[nod] = 1;

    for (i=0;i<v[nod].size();i++){
        vecin = v[nod][i];
        if (vecin != fth){
            dfs(vecin , nod , nivel + 1);
            d[nod] += d[vecin];
        }
    }

}
void dfs_lant(int nod){
    int i,vecin,ok=0,maxi,fiu;
    maxi=0;
    fiu=0;
    for (i=0;i<v[nod].size();i++){
        vecin=v[nod][i];
        if (vecin!=tt[nod]){
            ok=1;
            dfs_lant(vecin);
            if (d[vecin]>maxi){
                maxi=d[vecin];
                fiu=vecin;
            }
        }
    }
    if (!ok){ /// frunza
        lnt++;
        l[nod]=lnt; /// lantul din care apartine
        w[lnt].push_back(nod);
    }else { /// unim cu poz
        w[l[fiu]].push_back(nod);
        l[nod]=l[fiu];
        for (i=0;i<v[nod].size();i++){
            vecin=v[nod][i];
            if (vecin!=tt[nod] && vecin!=fiu)
                up[l[vecin]]=nod; /// din lantul vecinului trecem in lantul nodului
        }
    }
}
void build_aint (int lant , int p , int st , int dr){
    int mid = (st + dr)/2;

    if (st == dr){
        idx_aint[w[lant][st]] = p;
        return;
    }

    build_aint(lant , 2 * p , st , mid);
    build_aint(lant , 2 * p + 1 , mid + 1 , dr);


}
void update_aint (int lant , int p , int st , int dr , int l , int r){
    int mid , len , rest;
    if (st == dr){
        return;
    }
    mid=(st+dr)/2;
    if (l <= mid)
        update_aint(lant , 2 * p , st , mid , l , r);
    if (mid + 1 <= r)
        update_aint(lant , 2 * p + 1 , mid + 1 , dr , l , r);
    for (len = 1 ; len <= 20 ; len++){
        for (rest = 0 ; rest < len ; rest++)
            aint[lant][p][len * 100 + rest] = aint[lant][2 * p][len * 100 + rest] + aint[lant][2 * p + 1][len * 100 + rest];
    }
}
void update (int x , int y){
    if (l[x]!=l[y]){ /// avansam
        if (lvl[up[l[x]]]>lvl[up[l[y]]]){
            update ( up[l[x]] , y );

            update_aint (l[x] , 1 , 0 , w[l[x]].size()-1 , 0 , poz[x] );
        }
        else{
            update ( x , up[l[y]] );

            update_aint( l[y] , 1 , 0 , w[l[y]].size()-1 , 0 , poz[y] );
        }
    }
    else {
        update_aint( l[x] , 1 , 0 , w[l[x]].size()-1 , min(poz[x],poz[y]) , max(poz[x],poz[y]) );
    }
}
long long query_aint (int lant , int p , int st , int dr , int px , int py , int t1 , int t2){
    int mid , len , rest;
    long long sol = 0;
    if (px <= st && dr <= py){

        for (len = 1 ; len <= 20 ; len ++){
            for (rest = 0 ; rest < len ; rest++){
                //if (aint[lant][p][len * 100 + rest])
                  //  printf ("%d %d %d\n" , len , rest ,aint[lant][p][len * 100 + rest] );
                sol += 1LL * aint[lant][p][len * 100 + rest] * ( (t2 / len) + (t2 % len >= rest) - ((t1 - 1) / len) - ((t1 - 1) % len >= rest));
            }
        }

        return sol;
    }
    mid = (st + dr)/2;
    if (px <= mid)
        sol = sol + query_aint(lant , 2 * p , st , mid , px , py , t1 , t2);
    if (mid+1 <= py)
        sol = sol + query_aint(lant , 2 * p + 1 , mid + 1 , dr , px , py , t1 , t2);
    return sol;
}
long long query (int x , int y , int t1 , int t2){
    if (l[x] != l[y]){ /// avansam
        if (lvl[up[l[x]]]>lvl[up[l[y]]])
            return query(up[l[x]] , y , t1 , t2) + query_aint(l[x] , 1 , 0 , w[l[x]].size()-1 , 0 , poz[x] , t1 , t2);
        else{
            return query(x , up[l[y]] , t1 , t2) + query_aint(l[y] , 1 , 0 , w[l[y]].size()-1 , 0 , poz[y] , t1 , t2);
        }
    }
    else{
        return query_aint(l[x] , 1 , 0 , w[l[x]].size()-1 , min(poz[x],poz[y]) , max(poz[x],poz[y]) , t1 , t2);
    }
}
void adauga (int x , int y , int val , int op){
    int lca , nod , poz , len , i;
    nod = x;
    for (i = 0 ; i < 20 ; i++){
        f[nod] = op;
        nod = tt[nod];
    }

    nod = y;
    for (i = 0 ; i < 20 ; i++){
        if (f[nod] == op){
            lca = nod;
            break;
        }
        f[nod] = op;
        nod = tt[nod];
    }
    len = lvl[x] + lvl[y] - 2 * lvl[lca] + 1;

    nod = x;
    poz = 0;
    while (nod != tt[lca]){
        aint[l[nod]][idx_aint[nod]][len * 100 + poz] += val;
        poz++;
        nod = tt[nod];
    }

    nod = y;
    poz = len - 1;
    while (nod != lca){
        aint[l[nod]][idx_aint[nod]][len * 100 + poz] += val;
        poz--;
        nod = tt[nod];
    }
}
int main()
{
    FILE *fin = stdin;
    FILE *fout = stdout;
    int n , i , x , y , tip , k , q , t1 , t2 , p , vecin;
    fread (buff , 1 , 5000 , fin);
    n = getnr();
    for (i = 1 ; i < n ; i++){
        x = getnr();
        y = getnr();
        v[x].push_back(y);
        v[y].push_back(x);
    }

    dfs(1 , 0 , 1);
    dfs_lant(1);

    /// fiecare nod al catelea e
    for (i=1;i<=lnt;i++){
        reverse(w[i].begin(),w[i].end());
        p=0;
        for (vector <int> :: iterator j=w[i].begin();j!=w[i].end();j++){
            /// pozitia lui din lantul curent
            vecin=*j;
            poz[vecin]=p;
            p++;
        }
        aint[i].resize(w[i].size()*4);
        build_aint(i , 1 , 0 , w[i].size() - 1);
    }


    k = getnr();
    int op = 1;
    for (i = 1 ; i <= k ; i++){
        x = getnr();
        y = getnr();
        adauga(x , y , 1 , ++op);
        update(x , y);

    }
    q = getnr();
    for (i = 1 ; i <= q ; i++){
        tip = getnr();
        if (tip == 1){
            x = getnr();
            y = getnr();
            adauga(x , y , 1 , ++op);
            update (x , y);
        }
        else if (tip == 2){
            x = getnr();
            y = getnr();
            adauga(x , y , -1 , ++op);
            update (x , y);
        }
        else {
            x = getnr();
            y = getnr();
            t1 = getnr();
            t2 = getnr();
            fprintf (fout,"%lld\n",query (x , y , t1 , t2));
        }
    }
    return 0;
}

Compilation message

traffickers.cpp: In function 'void dfs(int, int, int)':
traffickers.cpp:40:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (i=0;i<v[nod].size();i++){
              ~^~~~~~~~~~~~~~
traffickers.cpp: In function 'void dfs_lant(int)':
traffickers.cpp:53:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (i=0;i<v[nod].size();i++){
              ~^~~~~~~~~~~~~~
traffickers.cpp:71:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (i=0;i<v[nod].size();i++){
                  ~^~~~~~~~~~~~~~
traffickers.cpp: In function 'int getnr()':
traffickers.cpp:16:19: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
             fread (buff , 1 , 5000 , stdin);
             ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
traffickers.cpp:25:19: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
             fread (buff , 1 , 5000 , stdin);
             ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
traffickers.cpp: In function 'int main()':
traffickers.cpp:197:11: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
     fread (buff , 1 , 5000 , fin);
     ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
traffickers.cpp: In function 'void adauga(int, int, int, int)':
traffickers.cpp:158:9: warning: 'lca' may be used uninitialized in this function [-Wmaybe-uninitialized]
     int lca , nod , poz , len , i;
         ^~~
# Verdict Execution time Memory Grader output
1 Correct 23 ms 8320 KB Output is correct
2 Correct 280 ms 27380 KB Output is correct
3 Correct 204 ms 21624 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2730 ms 170872 KB Output is correct
2 Correct 2410 ms 134656 KB Output is correct
3 Correct 2846 ms 191216 KB Output is correct
4 Correct 2606 ms 162808 KB Output is correct
5 Correct 2479 ms 149744 KB Output is correct
6 Correct 2544 ms 155768 KB Output is correct
7 Correct 2629 ms 160784 KB Output is correct
8 Correct 2844 ms 200540 KB Output is correct
9 Correct 2891 ms 207776 KB Output is correct
# Verdict Execution time Memory Grader output
1 Execution timed out 3588 ms 418016 KB Time limit exceeded
2 Execution timed out 3593 ms 508824 KB Time limit exceeded
3 Runtime error 2837 ms 524292 KB Execution killed with signal 9 (could be triggered by violating memory limits)
4 Execution timed out 3596 ms 328600 KB Time limit exceeded
5 Execution timed out 3592 ms 302304 KB Time limit exceeded
6 Runtime error 3118 ms 524292 KB Execution killed with signal 9 (could be triggered by violating memory limits)
7 Runtime error 2485 ms 524292 KB Execution killed with signal 9 (could be triggered by violating memory limits)
8 Runtime error 2539 ms 524292 KB Execution killed with signal 9 (could be triggered by violating memory limits)