/*
- Decompose the tree using centroid decomposition.
- Do something super similar to the example problem in this post: https://www.geeksforgeeks.org/centroid-decomposition-of-tree/
*/
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define sz(x) (int)(x).size()
#define mp make_pair
#define f first
#define s second
#define all(x) x.begin(), x.end()
using namespace std;
const int N=3e5+5;
vector<vector<int> > graph(N),centroid_graph(N);
vector<int> visited(N),siz(N),local(N),what(N);
void dfs(int tr,int par)
{
siz[tr]=1;
for(auto p:graph[tr])
{
if(visited[p]||p==par)
continue;
dfs(p,tr);
siz[tr]+=siz[p];
}
}
int find_centroid(int tr,int n,int par)
{
for(auto p:graph[tr])
{
if(p==par||visited[p])
continue;
if(siz[p]>n/2)
return find_centroid(p,n,tr);
}
return tr;
}
int decompose(int tr)
{
dfs(tr,-1);
tr=find_centroid(tr,siz[tr],-1);
visited[tr]=1;
for(auto p:graph[tr])
{
if(visited[p])
continue;
int t=decompose(p);
centroid_graph[t].pb(tr);
centroid_graph[tr].pb(t);
}
return tr;
}
ll cnt=0;
vector<int> allowed(N),str,fin,start(N),finish(N);
void calculate(int tr,int par,int offset,int maxx,int minn)
{
if(what[tr]==0){
offset++;
maxx=max(maxx,offset);
if(offset==maxx)
{
str.pb(offset);
}
}
else{
offset--;
minn=min(minn,offset);
if(offset==minn)
{
fin.pb(-1*offset);
}
}
for(auto p:graph[tr])
{
if(allowed[p]==0||p==par)
continue;
calculate(p,tr,offset,maxx,minn);
}
}
void solve(int tr,int par)
{
for(auto p:centroid_graph[tr])
{
if(p==par)
continue;
solve(p,tr);
}
int off;
if(what[tr]==0)
off=1;
else
off=-1;
vector<int> s,f;
for(auto p:graph[tr])
{
if(allowed[p]){
calculate(p,tr,0,0,0);
for(auto d:str)
{
if(off+d>=0)
cnt+=finish[d+off];
s.pb(d);
}
for(auto d:fin)
{
if(d-off>=0)
cnt+=start[d-off];
finish[d]++;
f.pb(d);
}
for(auto d:str)
start[d]++;
str.clear();
fin.clear();
}
}
allowed[tr]=1;
if(what[tr]==0)
cnt+=finish[1];
else
cnt+=start[1];
for(auto p:s)
start[p]=0;
for(auto p:f)
finish[p]=0;
}
int main()
{
int n;
scanf("%i",&n);
string s;
cin >> s;
for(int i=0;i<n;i++)
what[i+1]=s[i]==')';
for(int i=1;i<n;i++)
{
int a,b;
scanf("%i %i",&a,&b);
graph[a].pb(b);
graph[b].pb(a);
}
int root=decompose(1);
solve(root,-1);
printf("%lld\n",cnt);
return 0;
}
Compilation message
zagrade.cpp: In function 'int main()':
zagrade.cpp:134:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%i",&n);
~~~~~^~~~~~~~~
zagrade.cpp:142:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%i %i",&a,&b);
~~~~~^~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
23 ms |
22648 KB |
Output is correct |
2 |
Correct |
24 ms |
22776 KB |
Output is correct |
3 |
Correct |
23 ms |
22976 KB |
Output is correct |
4 |
Correct |
23 ms |
22976 KB |
Output is correct |
5 |
Correct |
22 ms |
22976 KB |
Output is correct |
6 |
Correct |
25 ms |
22976 KB |
Output is correct |
7 |
Correct |
24 ms |
23056 KB |
Output is correct |
8 |
Correct |
23 ms |
23056 KB |
Output is correct |
9 |
Correct |
23 ms |
23056 KB |
Output is correct |
10 |
Correct |
22 ms |
23056 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
466 ms |
60840 KB |
Output is correct |
2 |
Correct |
473 ms |
62980 KB |
Output is correct |
3 |
Correct |
478 ms |
62980 KB |
Output is correct |
4 |
Correct |
483 ms |
63236 KB |
Output is correct |
5 |
Correct |
445 ms |
63236 KB |
Output is correct |
6 |
Correct |
488 ms |
63236 KB |
Output is correct |
7 |
Correct |
479 ms |
63236 KB |
Output is correct |
8 |
Correct |
443 ms |
63236 KB |
Output is correct |
9 |
Correct |
447 ms |
63236 KB |
Output is correct |
10 |
Correct |
443 ms |
65084 KB |
Output is correct |
11 |
Correct |
442 ms |
65084 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
23 ms |
22648 KB |
Output is correct |
2 |
Correct |
24 ms |
22776 KB |
Output is correct |
3 |
Correct |
23 ms |
22976 KB |
Output is correct |
4 |
Correct |
23 ms |
22976 KB |
Output is correct |
5 |
Correct |
22 ms |
22976 KB |
Output is correct |
6 |
Correct |
25 ms |
22976 KB |
Output is correct |
7 |
Correct |
24 ms |
23056 KB |
Output is correct |
8 |
Correct |
23 ms |
23056 KB |
Output is correct |
9 |
Correct |
23 ms |
23056 KB |
Output is correct |
10 |
Correct |
22 ms |
23056 KB |
Output is correct |
11 |
Correct |
466 ms |
60840 KB |
Output is correct |
12 |
Correct |
473 ms |
62980 KB |
Output is correct |
13 |
Correct |
478 ms |
62980 KB |
Output is correct |
14 |
Correct |
483 ms |
63236 KB |
Output is correct |
15 |
Correct |
445 ms |
63236 KB |
Output is correct |
16 |
Correct |
488 ms |
63236 KB |
Output is correct |
17 |
Correct |
479 ms |
63236 KB |
Output is correct |
18 |
Correct |
443 ms |
63236 KB |
Output is correct |
19 |
Correct |
447 ms |
63236 KB |
Output is correct |
20 |
Correct |
443 ms |
65084 KB |
Output is correct |
21 |
Correct |
442 ms |
65084 KB |
Output is correct |
22 |
Correct |
968 ms |
65084 KB |
Output is correct |
23 |
Correct |
894 ms |
65084 KB |
Output is correct |
24 |
Correct |
932 ms |
65084 KB |
Output is correct |
25 |
Correct |
972 ms |
65084 KB |
Output is correct |
26 |
Correct |
501 ms |
65084 KB |
Output is correct |
27 |
Correct |
516 ms |
65084 KB |
Output is correct |
28 |
Correct |
563 ms |
65084 KB |
Output is correct |
29 |
Correct |
483 ms |
65276 KB |
Output is correct |
30 |
Correct |
522 ms |
65276 KB |
Output is correct |
31 |
Correct |
181 ms |
65276 KB |
Output is correct |
32 |
Correct |
455 ms |
65276 KB |
Output is correct |