#include <bits/stdc++.h>
#define int long long
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[bigRegion[i]][region[fiu]] += 1LL * cntAbove[bigRegion[i]];
}
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;
}
signed main()
{
cin >> n >> r >> q;
cin >> region[1];
cntRegion[region[1]] ++;
nodesFromRegion[region[1]].push_back(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(long long i = 1; i <= r; i ++)
{
if(bigIdx[i] == 0)
{
continue;
}
for(auto it : nodesFromRegion[i])
{
sumePartiale[timp[it].first] ++;
}
for(long long j = 1; j <= n; j ++)
{
sumePartiale[j] += 1LL * sumePartiale[j - 1];
}
for(long long j = 1; j <= cntSmallRegion; j ++)
{
for(auto it : nodesFromRegion[smallRegion[j]])
{
precalc[bigIdx[i]][j] += 1LL * (sumePartiale[timp[it].second] - sumePartiale[timp[it].first - 1]);
}
}
for(long long j = 1; j <= n; j ++)
{
sumePartiale[j] = 0;
}
}
while(q--)
{
long long 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
{
long long 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:136:25: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
136 | while(i < lista[a].size() && j < lista[b].size())
| ~~^~~~~~~~~~~~~~~~~
regions.cpp:136:48: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
136 | while(i < lista[a].size() && j < lista[b].size())
| ~~^~~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
5 ms |
10304 KB |
Output is correct |
2 |
Correct |
5 ms |
10320 KB |
Output is correct |
3 |
Correct |
8 ms |
10320 KB |
Output is correct |
4 |
Correct |
9 ms |
10320 KB |
Output is correct |
5 |
Correct |
12 ms |
10320 KB |
Output is correct |
6 |
Correct |
21 ms |
10476 KB |
Output is correct |
7 |
Correct |
38 ms |
10524 KB |
Output is correct |
8 |
Correct |
44 ms |
10576 KB |
Output is correct |
9 |
Correct |
56 ms |
11348 KB |
Output is correct |
10 |
Correct |
85 ms |
11472 KB |
Output is correct |
11 |
Correct |
111 ms |
12112 KB |
Output is correct |
12 |
Correct |
132 ms |
13096 KB |
Output is correct |
13 |
Correct |
183 ms |
13504 KB |
Output is correct |
14 |
Correct |
224 ms |
14236 KB |
Output is correct |
15 |
Correct |
248 ms |
18972 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
1102 ms |
20388 KB |
Output isn't correct |
2 |
Incorrect |
1048 ms |
20260 KB |
Output isn't correct |
3 |
Incorrect |
1813 ms |
23812 KB |
Output isn't correct |
4 |
Correct |
298 ms |
14380 KB |
Output is correct |
5 |
Correct |
407 ms |
16840 KB |
Output is correct |
6 |
Correct |
947 ms |
16640 KB |
Output is correct |
7 |
Correct |
1233 ms |
19048 KB |
Output is correct |
8 |
Correct |
1286 ms |
27444 KB |
Output is correct |
9 |
Correct |
1797 ms |
30760 KB |
Output is correct |
10 |
Correct |
2660 ms |
37824 KB |
Output is correct |
11 |
Correct |
2732 ms |
34672 KB |
Output is correct |
12 |
Runtime error |
158 ms |
40864 KB |
Execution killed with signal 11 |
13 |
Runtime error |
153 ms |
41264 KB |
Execution killed with signal 11 |
14 |
Runtime error |
168 ms |
43336 KB |
Execution killed with signal 11 |
15 |
Runtime error |
177 ms |
42492 KB |
Execution killed with signal 11 |
16 |
Runtime error |
182 ms |
41972 KB |
Execution killed with signal 11 |
17 |
Runtime error |
156 ms |
42400 KB |
Execution killed with signal 11 |