답안 #649260

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
649260 2022-10-09T22:54:07 Z vladutpiele Regions (IOI09_regions) C++17
55 / 100
2911 ms 43888 KB
#include <bits/stdc++.h>

using namespace std;

const int nmax = 200000;
const int block = 1000;

long long n, r, q;
int region[nmax + 5], cntRegion[nmax + 5];
int bigRegion[nmax + 5], cntBigRegion, bigIdx[nmax + 5];
int smallRegion[nmax + 5], cntSmallRegion, smallIdx[nmax + 5];
long long cntAbove[nmax + 5], sol[205][25005], sumePartiale[nmax + 5];
long long precalc[205][25005];
int cntTimp, newtime;
int stiva[nmax + 5];
vector<pair<int, int>> lista[25005];
pair<int, int> timp[nmax + 5];
vector<int> nodesFromRegion[nmax + 5];
vector<int> g[nmax + 5];

void dfs(int fiu, int tata)
{
    newtime++;
    lista[region[fiu]].push_back(make_pair(fiu, newtime));
    timp[fiu].first = ++cntTimp;
    /// cntAbove[i] -> numarul de noduri de regiunea i(care este o regiune de tip BIG), care sunt stramosi ai nodului curent
    if(bigIdx[region[fiu]] != 0)
    {
        cntAbove[bigIdx[region[fiu]]] ++;
    }
    for(int i = 1; i <= cntBigRegion; i ++)
    {
        sol[bigIdx[bigRegion[i]]][region[fiu]] += 1LL * cntAbove[bigIdx[region[fiu]]];
    }
    for(auto it : g[fiu])
    {
        if(it == tata)
        {
            continue;
        }
        dfs(it, fiu);
    }
    if(bigIdx[region[fiu]] != 0)
    {
        cntAbove[bigIdx[region[fiu]]] ++;
    }
    newtime++;
    lista[region[fiu]].push_back(make_pair(fiu, newtime));
    timp[fiu].second = cntTimp;
}

int main()
{
    cin >> n >> r >> q;
    cin >> region[1];
    cntRegion[region[1]] ++;
    for(int i = 2; i <= n; i ++)
    {
        int p;
        cin >> p >> region[i];
        g[p].push_back(i);
        g[i].push_back(p);
        cntRegion[region[i]] ++;
        nodesFromRegion[region[i]].push_back(i);
    }
    for(int i = 1; i <= r; i ++)
    {
        if(cntRegion[i] >= block)
        {
            bigRegion[++cntBigRegion] = i;
            bigIdx[i] = cntBigRegion;
        }
        else
        {
            smallRegion[++cntSmallRegion] = i;
            smallIdx[i] = cntSmallRegion;
        }
    }

    /// in dfs calculez pentru tipurile 1 si 2, cand regiunea de sus este de tip BIG

    dfs(1, 0);

    /// imi propun sa calculez pentru tipul 3, cand regiunea de jos este de tip BIG, iar regiunea de sus este de tip SMALL

    for(int i = 1; i <= r; i ++)
    {
        if(bigIdx[i] == 0)
        {
            continue;
        }
        for(auto it : nodesFromRegion[i])
        {
            sumePartiale[timp[it].first] ++;
        }
        for(int j = 1; j <= n; j ++)
        {
            sumePartiale[j] += 1LL * sumePartiale[j - 1];
        }
        for(int j = 1; j <= cntSmallRegion; j ++)
        {
            for(auto it : nodesFromRegion[smallRegion[i]])
            {
                precalc[bigIdx[i]][j] += 1LL * (sumePartiale[timp[it].second] - sumePartiale[timp[it].first] - 1);
            }
        }
        for(int j = 1; j <= n; j ++)
        {
            sumePartiale[j] = 0;
        }
    }

    while(q--)
    {
        int a, b;
        cin >> a >> b;
        if(bigIdx[a] != 0)
        {
            /// cand regiunea de sus e de tip BIG
            cout << sol[bigIdx[a]][b] << '\n';
        }
        else
        {
            if(bigIdx[b] != 0)
            {
                /// cand regiunea de jos e BIG, dar cea de sus e SMALL
                cout << precalc[bigIdx[b]][smallIdx[a]] << '\n';
            }
            else
            {
                int i = 0, j = 0, vf = 0;
                long long deschise = 0, answer = 0;
                while(i < lista[a].size() && j < lista[b].size())
                {
                    pair<int, int> frst = lista[a][i];
                    pair<int, int> scnd = lista[b][j];
                    if(frst.second < scnd.second)
                    {
                        if(vf && frst.first == stiva[vf])
                        {
                            vf--;
                            deschise--;
                        }
                        else
                        {
                            stiva[++vf] = frst.first;
                            deschise++;
                        }
                        i++;
                    }
                    else
                    {
                        if(vf && scnd.first == stiva[vf])
                        {
                            vf--;
                        }
                        else
                        {
                            answer += 1LL * deschise;
                            stiva[++vf] = scnd.first;
                        }
                        j++;
                    }
                }
                cout << answer << '\n';
            }
        }
    }
    return 0;
}

Compilation message

regions.cpp: In function 'int main()':
regions.cpp:133:25: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  133 |                 while(i < lista[a].size() && j < lista[b].size())
      |                       ~~^~~~~~~~~~~~~~~~~
regions.cpp:133:48: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  133 |                 while(i < lista[a].size() && j < lista[b].size())
      |                                              ~~^~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 5 ms 10320 KB Output is correct
2 Correct 6 ms 10320 KB Output is correct
3 Correct 6 ms 10320 KB Output is correct
4 Correct 9 ms 10320 KB Output is correct
5 Correct 14 ms 10320 KB Output is correct
6 Correct 36 ms 10448 KB Output is correct
7 Correct 37 ms 10448 KB Output is correct
8 Correct 41 ms 10440 KB Output is correct
9 Correct 34 ms 11088 KB Output is correct
10 Correct 82 ms 11020 KB Output is correct
11 Correct 139 ms 11484 KB Output is correct
12 Correct 140 ms 12092 KB Output is correct
13 Correct 173 ms 12164 KB Output is correct
14 Correct 164 ms 12656 KB Output is correct
15 Correct 193 ms 16544 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 973 ms 17316 KB Output isn't correct
2 Incorrect 1092 ms 16960 KB Output isn't correct
3 Incorrect 1710 ms 20036 KB Output isn't correct
4 Correct 294 ms 12872 KB Output is correct
5 Correct 286 ms 15016 KB Output is correct
6 Correct 826 ms 14408 KB Output is correct
7 Correct 1253 ms 16044 KB Output is correct
8 Correct 928 ms 22796 KB Output is correct
9 Correct 1779 ms 23732 KB Output is correct
10 Correct 2206 ms 30136 KB Output is correct
11 Correct 2911 ms 26196 KB Output is correct
12 Incorrect 941 ms 26144 KB Output isn't correct
13 Incorrect 1478 ms 27416 KB Output isn't correct
14 Incorrect 1804 ms 31012 KB Output isn't correct
15 Incorrect 2495 ms 33004 KB Output isn't correct
16 Incorrect 2717 ms 41784 KB Output isn't correct
17 Incorrect 2636 ms 43888 KB Output isn't correct