QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#100737#5017. 相等树链1kri10 4754ms344348kbC++147.3kb2023-04-27 20:38:342023-04-27 20:38:35

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-04-27 20:38:35]
  • 评测
  • 测评结果:10
  • 用时:4754ms
  • 内存:344348kb
  • [2023-04-27 20:38:34]
  • 提交

answer

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#define ll long long
using namespace std;
int n;
ll ans;
namespace T1{
	int u[400005],v[400005],first[200005],nxt[400005];
	void init(){
		for (int i=2;i<=n;i++){
			scanf("%d",&u[i]);
			v[i]=i;
			nxt[i]=first[u[i]],first[u[i]]=i;
			u[i+n]=v[i],v[i+n]=u[i];
			nxt[i+n]=first[u[i+n]],first[u[i+n]]=i+n;
		}
		return;
	}
	vector<int> id;
	int _book[200005],book[200005];
	vector<int> e[200005];
	int fa[200005],depth[200005],sz[200005],son[200005];
	int idx,dfn[200005],dfo[200005],top[200005];
	void dfs1(int now,int f,int d){
		book[now]=1;
		fa[now]=f,depth[now]=d;
		sz[now]=1,son[now]=0;
		for (int i=first[now];i;i=nxt[i])
			if (v[i]!=f&&_book[v[i]]==1){
				e[now].push_back(v[i]);
				dfs1(v[i],now,d+1);
				sz[now]+=sz[v[i]];
				if (son[now]==0||sz[v[i]]>sz[son[now]])son[now]=v[i];
			}
		return;
	}
	void dfs2(int now,int t){
		dfn[now]=++idx;
		top[now]=t;
		if (son[now]!=0)dfs2(son[now],t);
		for (int i=0;i<(int)e[now].size();i++)
			if (e[now][i]!=son[now])dfs2(e[now][i],e[now][i]);
		dfo[now]=idx;
		return;
	}
	void build(int rt,vector<int> _id){
		id=_id;
		for (int i=0;i<(int)id.size();i++){
			_book[id[i]]=1;
			e[id[i]].clear();
		}
		dfs1(rt,0,0);
		idx=0;
		dfs2(rt,rt);
		return;
	}
	void clear(){
		for (int i=0;i<(int)id.size();i++)_book[id[i]]=book[id[i]]=0;
		return;
	}
	int lca(int a,int b){
		while(top[a]!=top[b]){
			if (depth[top[a]]<depth[top[b]])swap(a,b);
			a=fa[top[a]];
		}
		if (depth[a]<depth[b])return a;
		return b;
	}
	int dis(int a,int b){
		return depth[a]+depth[b]-2*depth[lca(a,b)];
	}
	bool in(int a,int b){//whether a is in b
		return dfn[a]>dfn[b]&&dfn[a]<=dfo[b];
	}
}
struct node{
	int x,y,l,c;
};
node add(node a,int z){
	if (a.x==-1)return a;
	if (T1::book[z]==0)return (node){-1,-1,-1,-1};
	a.c++;
	int l1=T1::dis(z,a.x);
	int l2=T1::dis(z,a.y);
	if (a.l==l1+l2)return a;
	if (l1==a.l+l2){
		a.y=z;
		a.l=l1;
		if (T1::depth[a.x]>T1::depth[a.y])swap(a.x,a.y);
		return a;
	}
	if (l2==a.l+l1){
		a.x=z;
		a.l=l2;
		if (T1::depth[a.x]>T1::depth[a.y])swap(a.x,a.y);
		return a;
	}
	a.x=a.y=a.l=a.c=-1;
	return a;
}
int x;
namespace QwQ{
	using namespace T1;
	ll ans;
	vector<node> d;
	vector<pair<int,int>> ins[200005];
	// pair<int,int> sta[200005];
	// int tot;
	struct DS1{
		int a[1000005];
		void add(int t,int v){
			a[n+t]+=v;
			return;
		}
		int ask(int t){
			return a[n+t];
		}
	}ds1;
	struct SGT{
		struct tree_node{
			int l,r,val;
			tree_node(){
				l=r=val=0;
				return;
			}
			void mem(){
				l=r=val=0;
				return;
			}
		}tree[20000005];
		int tree_cnt;
		void add(int &now,int nowl,int nowr,int pos,int val){
			if (now==0)now=++tree_cnt;
			tree[now].val+=val;
			if (nowl==nowr)return;
			int mid=(nowl+nowr)/2;
			if (pos<=mid)add(tree[now].l,nowl,mid,pos,val);
			else add(tree[now].r,mid+1,nowr,pos,val);
			return;
		}
		int ask(int now,int nowl,int nowr,int lt,int rt){
			if (now==0)return 0;
			if (nowl>=lt&&nowr<=rt)return tree[now].val;
			int mid=(nowl+nowr)/2,s=0;
			if (mid>=lt)s+=ask(tree[now].l,nowl,mid,lt,rt);
			if (mid+1<=rt)s+=ask(tree[now].r,mid+1,nowr,lt,rt);
			return s;
		}
		void clear(){
			while(tree_cnt>0)tree[tree_cnt].mem(),tree_cnt--;
		}
	}sgt;
	struct DS2{
		int root[1000005];
		void add(int t,int p,int v){
			if (dfn[p]+1<=n)sgt.add(root[t+n],1,n,dfn[p]+1,v);
			if (dfo[p]+1<=n)sgt.add(root[t+n],1,n,dfo[p]+1,-v);
			return;
		}
		int ask(int t,int p){
			return sgt.ask(root[t+n],1,n,1,dfn[p]);
		}
	}ds2;
	struct DS3{
		int root[1000005];
		void add(int t,int p,int v){
			sgt.add(root[t+n],1,n,dfn[p],v);
			return;
		}
		int ask(int t,int p){
			if (dfn[p]==dfo[p])return 0;
			return sgt.ask(root[t+n],1,n,dfn[p]+1,dfo[p]);
		}
	}ds3;
	void dfs(int now){
		for (int i=0;i<(int)ins[now].size();i++){
			int p=ins[now][i].first,c=ins[now][i].second;
			if (p==x)ans+=ds1.ask(depth[now]-c);
			else{
				int qwq=0;
				ans+=ds2.ask(depth[now]+depth[p]-c,p);
				ans+=ds3.ask(depth[now]-c,p);
			}
		}
		for (int i=0;i<(int)ins[now].size();i++){
			int p=ins[now][i].first,c=ins[now][i].second;
			ds1.add(c-depth[p],2);
			if (p==x)ds2.add(c,p,2);
			else ds2.add(c,p,1);
			ds3.add(c-depth[p],p,1);
		}
		for (int i=0;i<(int)e[now].size();i++)dfs(e[now][i]);
		for (int i=0;i<(int)ins[now].size();i++){
			int p=ins[now][i].first,c=ins[now][i].second;
			ds1.add(c-depth[p],-2);
			if (p==x)ds2.add(c,p,-2);
			else ds2.add(c,p,-1);
			ds3.add(c-depth[p],p,-1);
		}
		return;
	}
	void clear(int now){
		for (int i=0;i<(int)e[now].size();i++)clear(e[now][i]);
		for (int i=0;i<(int)ins[now].size();i++){
			int p=ins[now][i].first,c=ins[now][i].second;
			ds2.root[c+n]=0;
			ds3.root[c-depth[p]+n]=0;
		}
		return;
	}
	ll calc(vector<node> _d){
		ans=0;
		d=_d;
		int cnt=0;
		for (int i=0;i<(int)d.size();i++){
			if (d[i].x==x&&d[i].c==d[i].l)cnt++;
			if (d[i].x!=x)ins[d[i].x].push_back(make_pair(d[i].y,d[i].c));
			if (d[i].y!=x)ins[d[i].y].push_back(make_pair(d[i].x,d[i].c));
		}
		ans=1ll*cnt*(cnt-1);
		dfs(x);
		clear(x);
		sgt.clear();
		for (int i=0;i<(int)d.size();i++){
			if (d[i].x==x&&d[i].c==d[i].l)cnt++;
			if (d[i].x!=x)ins[d[i].x].clear();
			if (d[i].y!=x)ins[d[i].y].clear();
		}
		return ans;
	}
}
namespace T2{
	int u[400005],v[400005],first[200005],nxt[400005];
	void init(){
		for (int i=2;i<=n;i++){
			scanf("%d",&u[i]);
			v[i]=i;
			nxt[i]=first[u[i]],first[u[i]]=i;
			u[i+n]=v[i],v[i+n]=u[i];
			nxt[i+n]=first[u[i+n]],first[u[i+n]]=i+n;
		}
		return;
	}
	int book[200005];
	int sz[200005],sum,rt;
	void getrt(int now,int fa){
		sz[now]=1;
		int mx=0;
		for (int i=first[now];i;i=nxt[i])
			if (v[i]!=fa&&book[v[i]]==0){
				getrt(v[i],now);
				sz[now]+=sz[v[i]];
				mx=max(mx,sz[v[i]]);
			}
		mx=max(mx,sum-sz[now]);
		if (2*mx<=sum)rt=now;
		return;
	}
	int tot,c[200005];
	void getid(int now,int fa){
		c[++tot]=now;
		for (int i=first[now];i;i=nxt[i])
			if (v[i]!=fa&&book[v[i]]==0)getid(v[i],now);
		return;
	}
	node d[200005];
	void getd(int now,int fa,node s){
		d[now]=s;
		for (int i=first[now];i;i=nxt[i])
			if (v[i]!=fa&&book[v[i]]==0)getd(v[i],now,add(s,v[i]));
		return;
	}
	void work(int now){
		x=now;
		book[now]=1;
		tot=0;
		getid(now,0);
		vector<int> qwq;
		for (int i=1;i<=tot;i++)qwq.push_back(c[i]);
		T1::build(now,qwq);
		getd(now,0,{now,now,0,0});
		vector<node> awa;
		for (int i=2;i<=tot;i++)
			if (d[c[i]].x!=-1&&d[c[i]].y!=-1&&T1::book[d[c[i]].x]==1&&T1::book[d[c[i]].y]==1)
				awa.push_back(d[c[i]]);
		ans+=2;
		for (int i=0;i<awa.size();i++)
			if (awa[i].l==awa[i].c)ans+=2;
		ans+=QwQ::calc(awa);
		for (int i=first[now];i;i=nxt[i]){
			if (book[v[i]]==1)continue;
			tot=0;
			getid(v[i],0);
			awa.clear();
			for (int j=1;j<=tot;j++)
				if (d[c[j]].x!=-1&&d[c[j]].y!=-1&&T1::book[d[c[j]].x]==1&&T1::book[d[c[j]].y]==1)
					awa.push_back(d[c[j]]);
			ans-=QwQ::calc(awa);
		}
		T1::clear();
		getrt(now,0);
		for (int i=first[now];i;i=nxt[i]){
			if (book[v[i]]==1)continue;
			sum=sz[v[i]],rt=0;
			getrt(v[i],now);
			work(rt);
		}
		return;
	}
}
int main(){
	cin>>n;
	T1::init();
	T2::init();
	T2::work(1);
	cout<<ans/2<<endl;
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Subtask #1:

score: 10
Accepted

Test #1:

score: 10
Accepted
time: 63ms
memory: 248452kb

input:

5000
1296 1400 867 4533 1296 2007 2059 115 821 2960 3187 1597 2409 2708 4743 4778 1345 3967 911 3400 4249 3793 339 3145 3490 607 4148 3513 3264 3852 568 775 828 1348 423 3678 305 1938 1096 1373 2662 1048 4328 4208 203 779 3103 3372 4523 192 264 792 4943 2211 2494 3513 3555 4935 3277 3390 4624 128 18...

output:

76002

result:

ok 1 number(s): "76002"

Test #2:

score: 0
Accepted
time: 64ms
memory: 248532kb

input:

5000
1820 281 610 3735 3580 3994 2060 2424 3338 2859 281 532 1286 1771 825 3738 3793 2260 556 4068 3793 4169 4411 4941 122 4270 4711 524 4037 2508 50 3343 2030 1151 4002 533 2994 1440 1762 3851 3050 4470 555 1979 3178 3933 3793 281 4810 520 3793 3535 2526 4422 2859 1561 1544 649 4544 2882 1236 2749 ...

output:

604316

result:

ok 1 number(s): "604316"

Test #3:

score: 0
Accepted
time: 68ms
memory: 250636kb

input:

5000
4333 51 707 3055 3433 1451 1305 1431 3081 302 1633 88 2024 441 120 4650 3927 4970 2578 3170 4245 4204 2102 4954 3140 1039 360 3173 4203 4927 4437 4337 4502 1712 3598 2968 2 4884 1260 1768 585 1815 4346 2938 4638 4886 4482 1095 1452 298 2702 2257 1375 2819 4482 711 220 396 3907 4792 2798 4445 42...

output:

912032

result:

ok 1 number(s): "912032"

Test #4:

score: 0
Accepted
time: 109ms
memory: 250492kb

input:

5000
362 4710 4997 4405 4728 3964 4258 3568 4997 2924 2931 4997 1094 2174 2220 127 4739 260 2591 4130 4916 1614 1408 324 2924 3272 4997 4020 2924 4216 2924 2931 2924 4783 271 1101 2924 246 4953 2553 4588 2924 1770 3738 4617 2508 2486 2137 1348 4847 2632 596 1011 1442 1287 4665 2924 2203 4411 726 109...

output:

1176721

result:

ok 1 number(s): "1176721"

Test #5:

score: 0
Accepted
time: 56ms
memory: 250532kb

input:

5000
3579 3530 3328 388 4864 4954 4597 3600 2428 1610 4533 1797 427 1296 3595 3861 4703 2914 4194 3195 451 585 3600 1134 1649 470 2049 2843 2845 3473 26 845 484 3301 1929 1342 1937 2003 1543 832 2301 2543 1889 1211 1619 1937 4471 585 4440 3600 1398 4687 2931 3982 2334 589 388 4012 873 66 2406 3861 1...

output:

1226857

result:

ok 1 number(s): "1226857"

Subtask #2:

score: 0
Time Limit Exceeded

Test #6:

score: 20
Accepted
time: 3060ms
memory: 321948kb

input:

200000
13177 40498 104798 83659 186055 32788 86489 72123 13521 134868 158968 60124 166316 163390 120935 103000 83938 57807 97940 40447 137723 154683 191864 59080 102808 3969 21451 165592 128776 49468 4101 26441 139317 59503 18053 118809 187783 149816 21609 98521 165692 52964 60425 23437 29614 106886...

output:

5859368

result:

ok 1 number(s): "5859368"

Test #7:

score: 0
Accepted
time: 4754ms
memory: 344348kb

input:

200000
161252 109349 161307 131176 54282 35989 53345 116328 52886 20845 166068 198634 185607 110703 32172 153437 50060 194586 193712 73284 32556 105087 55275 157714 22357 182552 31342 100889 145473 91759 18280 144489 108133 130988 11561 20028 121278 138065 83647 33848 33634 31990 198971 110781 12801...

output:

110388948

result:

ok 1 number(s): "110388948"

Test #8:

score: -20
Time Limit Exceeded

input:

200000
36915 117643 88659 78272 142053 101722 71138 149291 152470 118051 45210 31645 187500 22733 178345 55170 28768 44890 26946 76823 76271 9886 197447 130337 74747 175940 118067 191159 19884 113644 73935 160371 97288 153196 50668 47567 113533 73075 90904 115114 191694 127924 127338 41621 134964 59...

output:


result:


Subtask #3:

score: 0
Skipped

Dependency #2:

0%

Subtask #4:

score: 0
Skipped

Dependency #1:

100%
Accepted

Dependency #2:

0%