답안 #359271

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
359271 2021-01-26T15:00:09 Z nicolaalexandra 관광지 (IZhO14_shymbulak) C++14
20 / 100
125 ms 19312 KB
#include <bits/stdc++.h>
#define DIM 200010
#define DIMBUFF 7000000
using namespace std;

struct segment_tree{
    int maxi,maxi2;
    int cnt,cnt2; /// cate noduri din arborele initial
    int lazy;
} aint[DIM*4];

vector <int> L[DIM],s;
vector <pair<int,int> > w;
int viz[DIM],fth[DIM],f[DIM],v[DIM],dist[DIM];
pair <int,int> dp[DIM];
char buff[DIMBUFF];
int n,i,x,y,k,sol,sol_cnt,pos;


void dfs (int nod, int tata){
    viz[nod] = 1;
    s.push_back (nod);
    for (auto vecin : L[nod]){
        if (vecin == tata)
            continue;
        if (!viz[vecin])
            dfs (vecin,nod);
        else {
            if (viz[vecin] == 1){

                int poz = s.size()-1;
                while (poz >= 0 && s[poz] != vecin){
                    v[++k] = s[poz];
                    poz--;
                }
                v[++k] = vecin;
            }}}

    s.pop_back();
    viz[nod] = 2; /// nu mai e in stiva
}

void dfs2 (int nod, int tata){

    for (auto vecin : L[nod]){
        if (vecin != tata && !f[vecin])
            dfs2 (vecin,nod);
    }

    w.clear();
    dp[nod].second = 1;
    for (auto vecin : L[nod]){
        if (vecin == tata || f[vecin])
            continue;

        if (dp[nod].first + dp[vecin].first + 1 > sol){
            sol = dp[nod].first + dp[vecin].first + 1;
            sol_cnt = dp[nod].second * dp[vecin].second * 2;
        } else {
            if (dp[nod].first + dp[vecin].first + 1 == sol)
                sol_cnt += dp[nod].second * dp[vecin].second * 2;
        }

        if (dp[vecin].first + 1 > dp[nod].first){
            dp[nod].first = dp[vecin].first + 1;
            dp[nod].second = dp[vecin].second;
        } else {
            if (dp[vecin].first + 1 == dp[nod].first)
                dp[nod].second += dp[vecin].second;
        }}}


void update_nod (int nod){
    int fiu_st = nod<<1, fiu_dr = (nod<<1)|1;

    aint[nod] = aint[fiu_st];

    if (aint[fiu_dr].maxi > aint[nod].maxi){
        aint[nod].maxi2 = aint[nod].maxi;
        aint[nod].cnt2 = aint[nod].cnt;

        aint[nod].maxi = aint[fiu_dr].maxi;
        aint[nod].cnt = aint[fiu_dr].cnt;
    } else {
        if (aint[fiu_dr].maxi == aint[nod].maxi)
            aint[nod].cnt += aint[fiu_dr].cnt;
        else {
            if (aint[fiu_dr].maxi > aint[nod].maxi2){
                aint[nod].maxi2 = aint[fiu_dr].maxi;
                aint[nod].cnt2 = aint[fiu_dr].cnt;
            } else {
                if (aint[fiu_dr].maxi == aint[nod].maxi2)
                    aint[nod].cnt2 += aint[fiu_dr].cnt;
            }}}

    if (aint[fiu_dr].maxi2 > aint[nod].maxi2){
        aint[nod].maxi2 = aint[fiu_dr].maxi2;
        aint[nod].cnt2 = aint[fiu_dr].cnt2;
    } else {
        if (aint[fiu_dr].maxi2 == aint[nod].maxi2)
            aint[nod].cnt2 += aint[fiu_dr].cnt2;
    }

}

void update_lazy (int nod, int st, int dr){
    if (!aint[nod].lazy)
        return;
    if (st != dr){
        int fiu_st = nod<<1, fiu_dr = (nod<<1)|1;
        aint[fiu_st].maxi += aint[nod].lazy;
        aint[fiu_st].maxi2 += aint[nod].lazy;
        aint[fiu_st].lazy += aint[nod].lazy;

        aint[fiu_dr].maxi += aint[nod].lazy;
        aint[fiu_dr].maxi2 += aint[nod].lazy;
        aint[fiu_dr].lazy += aint[nod].lazy;
    }
    aint[nod].lazy = 0;
}

void build (int nod, int st, int dr){
    if (st == dr){
        aint[nod].maxi = dist[st];
        aint[nod].cnt = dp[v[st]].second;
        return;
    }
    int mid = (st+dr)>>1;
    build (nod<<1,st,mid);
    build ((nod<<1)|1,mid+1,dr);
    update_nod (nod);
}

void update (int nod, int st, int dr, int x, int y, int val){
    if (x > y)
        return;

    update_lazy (nod,st,dr);
    if (x <= st && dr <= y){
        aint[nod].maxi += val;
        aint[nod].maxi2 += val;
        aint[nod].lazy += val;
        update_lazy (nod,st,dr);
        return;
    }
    int mid = (st+dr)>>1;
    if (x <= mid)
        update (nod<<1,st,mid,x,y,val);
    if (y > mid)
        update ((nod<<1)|1,mid+1,dr,x,y,val);
    update_lazy (nod<<1,st,mid);
    update_lazy ((nod<<1)|1,mid+1,dr);

    update_nod (nod);
}


int get_nr (){

    while (!(buff[pos] >= '0' && buff[pos] <= '9'))
        pos++;

    int nr = 0;
    while (buff[pos] >= '0' && buff[pos] <= '9'){
        nr = nr * 10 + buff[pos] - '0';
        pos++;
    }

    return nr;

}

int main (){

    //FILE *fin = fopen ("date.in","r");
    //FILE *fout = fopen ("date.out","w");

    FILE *fin = stdin;
    FILE *fout = stdout;

    fread (buff,1,DIMBUFF,fin);

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

    dfs (1,0);

    for (i=1;i<=k;i++)
        f[v[i]] = 1;

    for (i=1;i<=k;i++)
        dfs2 (v[i],0);


    /// distantele
    int st = 2, dr = k, nr = 1;
    while (st < dr){
        dist[st] = dist[dr] = nr;
        nr++;
        st++, dr--;
    }

    if (k % 2 == 0)
        dist[st] = nr;

    for (i=1;i<=k;i++)
        dist[i] += dp[v[i]].first;

    /// trb sa retin doua maxime in aint??

    build (1,1,k);

    /// lg ciclu impara => nu pot sa am mai mult de un drum minim intre doua noduri


    int poz = k / 2 + 1;
    for (i=1;i<=k;i++){
        /// query

        if (aint[1].maxi != dp[v[i]].first){
            if (aint[1].maxi + dp[v[i]].first > sol){
                sol = aint[1].maxi + dp[v[i]].first;
                sol_cnt = dp[v[i]].second * aint[1].cnt;
            } else {
                if (aint[1].maxi + dp[v[i]].first == sol)
                    sol_cnt += dp[v[i]].second * aint[1].cnt;
            }
        } else {

            if (aint[1].cnt - dp[v[i]].second){

                if (aint[1].maxi * 2 > sol){
                    sol = aint[1].maxi * 2;
                    sol_cnt = dp[v[i]].second * (aint[1].cnt - dp[v[i]].second);
                } else {
                    if (aint[1].maxi * 2 == sol)
                        sol_cnt += dp[v[i]].second * (aint[1].cnt - dp[v[i]].second);
                }

            } else { /// iau al doilea maxim

                if (dp[v[i]].first + aint[1].maxi2 > sol){
                    sol = dp[v[i]].first + aint[1].maxi2;
                    sol_cnt = dp[v[i]].second * aint[1].cnt2;
                } else {
                    if (dp[v[i]].first + aint[1].maxi2 == sol)
                        sol_cnt += dp[v[i]].second * aint[1].cnt2;
                }}}


        /// update

        if (k % 2){ /// lg impara
            if (poz >= k/2 + 1){
                update (1,1,k,i+1,poz,-1);
                update (1,1,k,poz+2,k,1);

                if (poz == k)
                    update (1,1,k,2,i,1);
                else update (1,1,k,1,i,1);
            } else {

                update (1,1,k,i+1,k,-1);
                update (1,1,k,poz+2,i,1);
                update (1,1,k,1,poz,-1);

            }
        } else {

            if (poz >= k/2 + 1){
                update (1,1,k,i+1,poz,-1);
                update (1,1,k,poz+1,n,1);
                update (1,1,k,1,i,1);
            } else {
                update (1,1,k,i+1,n,-1);
                update (1,1,k,poz+1,i,1);
                update (1,1,k,1,poz,-1);
            }


        }

        poz++;
        if (poz > k)
            poz = 1;
    }


    /// trebuie sa mai verific si perechile la care pot sa ajung in doua moduri
    if (k % 2 == 0){
        for (i=1;i<=k;i++){
            int poz = i + k/2;
            if (poz > k)
                poz -= k;

            if (dp[v[i]].first + dp[v[poz]].first + k/2 > sol){
                sol = dp[v[i]].first + dp[v[poz]].first + k/2;
                sol_cnt = dp[v[i]].second * dp[v[poz]].second;
            } else {
                if (dp[v[i]].first + dp[v[poz]].first + k/2 == sol)
                    sol_cnt += dp[v[i]].second * dp[v[poz]].second;
            }
        }
    }


    fprintf(fout,"%d",sol_cnt/2);
    //cout<<sol_cnt / 2;


    return 0;
}

Compilation message

shymbulak.cpp: In function 'int main()':
shymbulak.cpp:181:11: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
  181 |     fread (buff,1,DIMBUFF,fin);
      |     ~~~~~~^~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 5100 KB Output is correct
2 Correct 4 ms 5100 KB Output is correct
3 Correct 4 ms 5100 KB Output is correct
4 Correct 4 ms 5100 KB Output is correct
5 Correct 4 ms 5100 KB Output is correct
6 Incorrect 4 ms 5100 KB Output isn't correct
7 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 5 ms 5228 KB Output is correct
2 Correct 4 ms 5100 KB Output is correct
3 Correct 4 ms 5228 KB Output is correct
4 Correct 4 ms 5100 KB Output is correct
5 Correct 5 ms 5356 KB Output is correct
6 Correct 5 ms 5356 KB Output is correct
7 Correct 5 ms 5356 KB Output is correct
8 Correct 5 ms 5356 KB Output is correct
9 Correct 5 ms 5356 KB Output is correct
10 Correct 5 ms 5356 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 51 ms 10220 KB Output is correct
2 Correct 43 ms 11904 KB Output is correct
3 Correct 116 ms 19312 KB Output is correct
4 Correct 29 ms 12140 KB Output is correct
5 Correct 31 ms 12140 KB Output is correct
6 Incorrect 125 ms 17260 KB Output isn't correct
7 Halted 0 ms 0 KB -