답안 #364699

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
364699 2021-02-09T17:40:50 Z Ruxandra985 관광지 (IZhO14_shymbulak) C++14
0 / 100
94 ms 18412 KB
#include <bits/stdc++.h>
#define DIM 200010
using namespace std;
int low[DIM],niv[DIM],f[DIM],st[DIM],elem,sol;
int w[DIM];
vector <int> v[DIM],s[DIM];
pair <int , int> lnt[DIM];
pair <int , int> diam[DIM];

pair <int , int> aint[DIM];
int lzy[DIM];

void dfs (int nod,int tata){
    int i,vecin;
    low[nod]=niv[nod];
    st[++elem]=nod;
    for (i=0;i<v[nod].size();i++){
        vecin=v[nod][i];
        if (vecin!=tata){
            if (!niv[vecin]){
                niv[vecin]=1+niv[nod];
                dfs (vecin,nod);
                low[nod]=min(low[nod],low[vecin]);
                ///VERIFICARE
                if (low[vecin]>=niv[nod]){
                    sol++;
                    do{
                        s[sol].push_back(st[elem]);
                        elem--;
                    }while (st[elem+1]!=vecin);
                    s[sol].push_back(nod);
                }
            }
            else low[nod]=min(low[nod],niv[vecin]);
        }
    }
}

void dfs2 (int nod , int tt){
    int i , vecin;
    int maxi1 = 0 , maxi2 = 0 , fmaxi1 = 1 , fmaxi2 = 1 , n1 = 1 , n2 = 1;

    /// first e lantul maxim , second e diametrul max din subarb

    for (i = 0 ; i < v[nod].size() ; i++){
        vecin = v[nod][i];
        if (f[vecin] || vecin == tt)
            continue; /// nu

        dfs2(vecin , nod);

        if (lnt[vecin].first > maxi1){
            maxi2 = maxi1;
            fmaxi2 = fmaxi1;
            n2 = n1;

            maxi1 = lnt[vecin].first;
            fmaxi1 = lnt[vecin].second;
            n1 = 1;
        }
        else if (lnt[vecin].first == maxi1){
            fmaxi1 += lnt[vecin].second;
            n1++;
        }
        else if (lnt[vecin].first > maxi2){
            maxi2 = lnt[vecin].first;
            fmaxi2 = lnt[vecin].second;
            n2 = 1;
        }
        else if (lnt[vecin].first == maxi2){
            fmaxi2 += lnt[vecin].second;
            n2++;
        }

    }
    lnt[nod] = make_pair(maxi1 + 1 , fmaxi1);
    if (n1 != 1)
        diam[nod] = make_pair(2 * maxi1 + 1 , n1 * (n1 - 1) / 2);
    else diam[nod] = make_pair(maxi1 + maxi2 + 1 , n2);


}

inline void lazy_update (int nod,int st,int dr){
    if (!lzy[nod]) /// nu ii trb lazy
        return;
    if (st<dr){ /// nu e frunza
        lzy[2*nod]+=lzy[nod]; /// pass lazy
        lzy[2*nod+1]+=lzy[nod];
    }
    aint[nod].first+=lzy[nod];
    lzy[nod]=0;
}

void build (int nod , int st , int dr , int len){
    int mid = (st + dr) / 2;

    if (st == dr){
        aint[nod] = make_pair(lnt[w[st]].first + min(st - 1 , len - st + 1) , lnt[w[st]].second);
        return;
    }

    build (2 * nod , st , mid , len);
    build (2 * nod + 1 , mid + 1 , dr , len);

    if (aint[2 * nod].first > aint[2 * nod].second)
        aint[nod] = aint[2 * nod];
    else if (aint[2 * nod].first < aint[2 * nod].second)
        aint[nod] = aint[2 * nod + 1];
    else aint[nod] = make_pair(aint[2 * nod].first , aint[2 * nod].second + aint[2 * nod + 1].second);



}

int solmax , nr;

void query (int nod , int st , int dr , int l , int r , int start){
    int mid = (st + dr) / 2;

    lazy_update (nod,st,dr);
    if (l <= st && dr <= r){

        if (solmax < aint[nod].first + lnt[w[start]].first - 1){
            solmax = aint[nod].first + lnt[w[start]].first - 1;
            nr = aint[nod].second * lnt[w[start]].second;
        }
        else if (solmax == aint[nod].first + lnt[w[start]].first - 1)
            nr += aint[nod].second * lnt[w[start]].second;

        return;
    }

    if (l <= mid)
        query(2 * nod , st , mid , l , r , start);
    if (mid + 1 <= r)
        query(2 * nod + 1 , mid + 1 ,dr , l , r , start);

    lazy_update (2*nod,st,mid);
    lazy_update (2*nod+1,mid+1,dr);

}

void update (int nod , int st , int dr , int l , int r , int val){
    int mid = (st + dr) / 2;

    lazy_update (nod,st,dr);
    if (l <= st && dr <= r){

        lzy[nod] += val;
        lazy_update (nod,st,dr);

        return;
    }

    if (l <= mid)
        update(2 * nod , st , mid , l , r , val);
    if (mid + 1 <= r)
        update(2 * nod + 1 , mid + 1 ,dr , l , r , val);

    lazy_update (2*nod,st,mid);
    lazy_update (2*nod+1,mid+1,dr);

    if (aint[2 * nod].first > aint[2 * nod + 1].first)
        aint[nod] = aint[2 * nod];
    else if (aint[2 * nod].first < aint[2 * nod + 1].first)
        aint[nod] = aint[2 * nod + 1];
    else aint[nod] = make_pair(aint[2 * nod].first , aint[2 * nod].second + aint[2 * nod + 1].second);



}


void upd_fr (int nod , int st , int dr ,int x , int val){
    int mid = (st + dr) / 2;

    lazy_update (nod,st,dr);
    if (st == dr){

        if (val == 1)
            aint[nod].second *= 2;
        else aint[nod].second /= 2;

        return;
    }

    if (x <= mid)
        upd_fr(2 * nod , st , mid , x , val);
    else upd_fr(2 * nod + 1 , mid + 1 ,dr , x , val);

    lazy_update (2*nod,st,mid);
    lazy_update (2*nod+1,mid+1,dr);

    if (aint[2 * nod].first > aint[2 * nod + 1].first)
        aint[nod] = aint[2 * nod];
    else if (aint[2 * nod].first < aint[2 * nod + 1].first)
        aint[nod] = aint[2 * nod + 1];
    else aint[nod] = make_pair(aint[2 * nod].first , aint[2 * nod].second + aint[2 * nod + 1].second);



}


int main()
{
    FILE *fin = stdin;
    FILE *fout = stdout;
    int n , x , y , i , dmax , frq , j , len , middle , nod;
    fscanf (fin,"%d",&n);
    for (i = 1 ; i <= n ; i++){
        fscanf (fin,"%d%d",&x,&y);
        v[x].push_back(y);
        v[y].push_back(x);
    }

    /// pasul 1: gaseste ciclul

    for (i=1;i<=n;i++){
        if (!niv[i]){
            niv[i]=1;
            dfs (i,0);
        }
    }

    /// comp biconexa cu + 2 noduri

    for (i = 1 ; i <= sol ; i++){

        if (s[i].size() > 2){ /// asta !!

            for (j = 0 ; j < s[i].size() ; j++){
                w[j + 1] = s[i][j];
                f[s[i][j]] = 1;
            }

            len = s[i].size();

        }

    }

    /// pt fiecare nod din ciclu, construiesti diametrul + lantul maxim
    dmax = 0;
    frq = 0;

    for (i = 1 ; i <= len ; i++){

        dfs2 (w[i] , 0);

        if (dmax < diam[w[i]].first){
            frq = diam[w[i]].second;
            dmax = diam[w[i]].first;
        }
        else if (dmax == diam[w[i]].first)
            frq += diam[w[i]].second;

    }
    build (1 , 1 , len , len);

    /// daca distamta maxima = diametru maxim, mai adaugi si frq

    solmax = 0;
    nr = 0;

    if (len % 2 == 0){ /// cazul cand middle are 2 frecvente
        upd_fr (1 , 1 , len , 1 + len / 2 , 1);

        query (1 , 1 , len , 2 , len , 1);

        middle = 1 + len / 2;


        for (i = 2 ; i <= len ; i++){

            /// updatezi intervale
            nod = i;

            middle++;
            if (middle > len)
                upd_fr (1 , 1 , len , middle - len , 1);
            else
                upd_fr (1 , 1 , len , middle , 1);

            if (middle - 1 > len)
                upd_fr (1 , 1 , len , middle - 1 - len , -1);
            else
                upd_fr (1 , 1 , len , middle - 1 , -1);

            /// intre nod si middle - 1 scazi 1

            if (middle - 1 < len){
                update (1 , 1 , len , nod , middle - 1 , -1);
                update (1 , 1 , len , 1 , nod - 1 , 1);
                update (1 , 1 , len , middle , len , 1);

            }
            else if (middle - 1 == len){
                update (1 , 1 , len , nod , middle - 1 , -1);
                update (1 , 1 , len , 1 , nod - 1 , 1);
            }
            else {
                update (1 , 1 , len , nod , len , -1);
                update (1 , 1 , len , 1 , middle - 1 - len , -1);
                update (1 , 1 , len , middle - len , nod - 1 , 1);

            }


            /// query
            query (1 , 1 , len , 1 , i - 1 , i);

            if (i != len)
                query (1 , 1 , len , i + 1 , len , i);


        }


    }
    else {

        query (1 , 1 , len , 2 , len , 1);
        middle = len / 2 + 1;

        for (i = 2 ; i <= len ; i++){

            /// updatezi intervale
            nod = i;
            middle++;

            if (middle == len){
                update (1 , 1 , len , nod , middle - 1 , -1);

                update (1 , 1 , len , 1 , nod - 1 , 1);
            }
            else if (middle == len + 1){
                update (1 , 1 , len , nod , middle - 1 , -1);
                update (1 , 1 , len , 2 , nod - 1 , 1);
            }
            else if (middle < len){
                update (1 , 1 , len , nod , middle - 1 , -1);
                update (1 , 1 , len , middle + 1 , len , 1);
                update (1 , 1 , len , 1 , nod - 1 , 1);

            }
            else {
                update (1 , 1 , len , nod , len , -1);
                update (1 , 1 , len , 1 , middle - 1 - len , -1);

                update (1 , 1 , len , middle + 1 - len , nod - 1 , 1);

            }


            /// query
            query (1 , 1 , len , 1 , i - 1 , i);

            if (i != len)
                query (1 , 1 , len , i + 1 , len , i);


        }

    }

    nr /= 2;

    if (solmax == dmax)
        nr += frq;

    fprintf (fout,"%d",nr);

    return 0;
}

Compilation message

shymbulak.cpp: In function 'void dfs(int, int)':
shymbulak.cpp:17:15: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   17 |     for (i=0;i<v[nod].size();i++){
      |              ~^~~~~~~~~~~~~~
shymbulak.cpp: In function 'void dfs2(int, int)':
shymbulak.cpp:45:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   45 |     for (i = 0 ; i < v[nod].size() ; i++){
      |                  ~~^~~~~~~~~~~~~~~
shymbulak.cpp: In function 'int main()':
shymbulak.cpp:233:28: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  233 |             for (j = 0 ; j < s[i].size() ; j++){
      |                          ~~^~~~~~~~~~~~~
shymbulak.cpp:211:12: warning: ignoring return value of 'int fscanf(FILE*, const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  211 |     fscanf (fin,"%d",&n);
      |     ~~~~~~~^~~~~~~~~~~~~
shymbulak.cpp:213:16: warning: ignoring return value of 'int fscanf(FILE*, const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  213 |         fscanf (fin,"%d%d",&x,&y);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~
shymbulak.cpp:314:13: warning: 'len' may be used uninitialized in this function [-Wmaybe-uninitialized]
  314 |             if (i != len)
      |             ^~
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 9708 KB Output is correct
2 Correct 7 ms 9708 KB Output is correct
3 Correct 7 ms 9708 KB Output is correct
4 Correct 7 ms 9708 KB Output is correct
5 Incorrect 7 ms 9708 KB Output isn't correct
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 8 ms 9836 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 94 ms 18412 KB Output isn't correct
2 Halted 0 ms 0 KB -