Submission #212249

# Submission time Handle Problem Language Result Execution time Memory
212249 2020-03-22T15:43:15 Z nicolaalexandra Traffickers (RMI18_traffickers) C++14
60 / 100
3500 ms 61220 KB
/// nu mai ai ce discuta cu mn ruxandra :(

#include <bits/stdc++.h>
#define DIM 30002
#pragma GCC optimize("O3")
//#pragma GCC optimize("Ofast")
/*
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
*/
using namespace std;
class InParser {

private:

	FILE *fin;

	char *buff;

	int sp;



	char read_ch() {

		++sp;

		if (sp == 4096) {

			sp = 0;

			fread(buff, 1, 4096, fin);

		}

		return buff[sp];

	}



public:

	InParser(const char* nume) {

		fin = fopen(nume, "r");

		buff = new char[4096]();

		sp = 4095;

	}



	InParser& operator >> (int &n) {

		char c;

		while (!isdigit(c = read_ch()) && c != '-');

		int sgn = 1;

		if (c == '-') {

			n = 0;

			sgn = -1;

		} else {

			n = c - '0';

		}

		while (isdigit(c = read_ch())) {

			n = 10 * n + c - '0';

		}

		n *= sgn;

		return *this;

	}



	InParser& operator >> (long long &n) {

		char c;

		n = 0;

		while (!isdigit(c = read_ch()) && c != '-');

		long long sgn = 1;

		if (c == '-') {

			n = 0;

			sgn = -1;

		} else {

			n = c - '0';

		}

		while (isdigit(c = read_ch())) {

			n = 10 * n + c - '0';

		}

		n *= sgn;

		return *this;

	}

} in("traffickers.in");


class OutParser {

private:

    FILE *fout;

    char *buff;

    int sp;



    void write_ch(char ch) {

        if (sp == 50000) {

            fwrite(buff, 1, 50000, fout);

            sp = 0;

            buff[sp++] = ch;

        } else {

            buff[sp++] = ch;

        }

    }





public:

    OutParser(const char* name) {

        fout = fopen(name, "w");

        buff = new char[50000]();

        sp = 0;

    }

    ~OutParser() {

        fwrite(buff, 1, sp, fout);

        fclose(fout);

    }



    OutParser& operator << (int vu32) {

        if (vu32 <= 9) {

            write_ch(vu32 + '0');

        } else {

            (*this) << (vu32 / 10);

            write_ch(vu32 % 10 + '0');

        }

        return *this;

    }



    OutParser& operator << (long long vu64) {

        if (vu64 <= 9) {

            write_ch(vu64 + '0');

        } else {

            (*this) << (vu64 / 10);

            write_ch(vu64 % 10 + '0');

        }

        return *this;

    }



    OutParser& operator << (char ch) {

        write_ch(ch);

        return *this;

    }

    OutParser& operator << (const char *ch) {

        while (*ch) {

            write_ch(*ch);

            ++ch;

        }

        return *this;

    }

} out("traffickers.out");


vector <int> L[DIM];
vector <int> chains[DIM];

int aint[20][21][DIM*4];

int whatChain[DIM],chainFatherNode[DIM],Size[DIM],posAib[DIM];
int level[DIM],fth[DIM],w[22],aux[22];


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


void update_aint (int nod, int st, int dr, int poz, int val, int a, int b){
    if (st == dr){
        aint[a][b][nod] += val;
        return;
    }
    int mid = (st+dr)>>1;
    if (poz <= mid)
        update_aint (nod<<1,st,mid,poz,val,a,b);
    else update_aint((nod<<1)|1,mid+1,dr,poz,val,a,b);
    aint[a][b][nod] = aint[a][b][nod<<1] + aint[a][b][(nod<<1)|1];
}

void query_aint (int nod, int st, int dr, int x, int y, int a, int b){
    if (x <= st && dr <= y){
        sol_aint += aint[a][b][nod];
        return;
    }
    int mid = (st+dr)>>1;
    if (x <= mid)
        query_aint(nod<<1,st,mid,x,y,a,b);
    if (y > mid)
        query_aint((nod<<1)|1,mid+1,dr,x,y,a,b);
}

/*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){
    sol_aint = 0;
    query_aint (1,1,n,x,y,a,b);
    return sol_aint;
    //return query_aib (a,b,y) - query_aib (a,b,x-1);
}

void dfs (int nod, int tata){

    fth[nod] = tata;
    level[nod] = 1 + level[tata];
    Size[nod] = 1;
    int ok = 0, maxim = 0, poz = 0;
    for (auto vecin : L[nod]){
        if (vecin != tata){
            ok = 1;
            dfs (vecin,nod);

            Size[nod] += Size[vecin];

            if (Size[vecin] > maxim)
                maxim = Size[vecin], poz = vecin;

        }}

    if (!ok){
        nr_chains++;
        chains[nr_chains].push_back(0);
        chains[nr_chains].push_back(nod);

        whatChain[nod] = nr_chains;

    } else {

        chains[whatChain[poz]].push_back(nod);

        whatChain[nod] = whatChain[poz];

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


void drum (int x, int y){

    el = el2 = 0;

    while (x != y){
        if (level[x] > level[y]){
            w[++el] = x;
            x = fth[x];
        } else {
            aux[++el2] = y;
            y = fth[y];
        }
    }
    w[++el] = x;

    for (j=el2;j>=1;j--)
        w[++el] = aux[j];

}
void adauga (int x, int y){

    drum (x,y);

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

    int t = 0, lg = el;
    for (int i=1;i<=el;i++){
        int nod = w[i];

        update_aint (1,1,n,posAib[nod],1,t,lg);

        t++;
    }
}
void scoate (int x, int y){
    drum (x,y);

    int t = 0, lg = el;

    for (int i=1;i<=el;i++){
        int nod = w[i];
        update_aint (1,1,n,posAib[nod],-1,t,lg);

        t++;
    }
}

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

    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 t1, int t2){

    long long sol = 0;
    for (int a=0;a<20;++a){
        if (a > t2)
            break;
        for (int b=a+1;b<=20;++b){
            sum = 0;
            query_heavy (x,y,a,b);

            if (t2 >= a){

                int nr = (t2 - a) / b + 1;

                sol += sum * nr;
            }
            if (t1 >= a){

                int nr = (t1 - a) / b + 1;

                sol -= sum * nr;
            }}}

    return sol;
}
int main (){

    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;
        }


    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,t1-1,t2)<<"\n";
    }

    return 0;
}

Compilation message

traffickers.cpp: In function 'int main()':
traffickers.cpp:446:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (j=1;j<chains[i].size();++j){
                  ~^~~~~~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 7 ms 2944 KB Output is correct
2 Correct 14 ms 4736 KB Output is correct
3 Correct 16 ms 4608 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 390 ms 28280 KB Output is correct
2 Correct 378 ms 24056 KB Output is correct
3 Correct 343 ms 31176 KB Output is correct
4 Correct 351 ms 27640 KB Output is correct
5 Correct 416 ms 25336 KB Output is correct
6 Correct 370 ms 26616 KB Output is correct
7 Correct 372 ms 27384 KB Output is correct
8 Correct 347 ms 30712 KB Output is correct
9 Correct 310 ms 30968 KB Output is correct
# Verdict Execution time Memory Grader output
1 Execution timed out 3553 ms 53732 KB Time limit exceeded
2 Execution timed out 3509 ms 58708 KB Time limit exceeded
3 Execution timed out 3579 ms 60124 KB Time limit exceeded
4 Execution timed out 3552 ms 49904 KB Time limit exceeded
5 Execution timed out 3563 ms 52044 KB Time limit exceeded
6 Execution timed out 3579 ms 60044 KB Time limit exceeded
7 Execution timed out 3582 ms 61220 KB Time limit exceeded
8 Execution timed out 3573 ms 60816 KB Time limit exceeded