QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#327663#3307. Query on a Tree 17yz_lyWA 6ms9780kbC++143.0kb2024-02-15 11:48:472024-02-15 11:48:47

Judging History

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

  • [2024-02-15 11:48:47]
  • 评测
  • 测评结果:WA
  • 用时:6ms
  • 内存:9780kb
  • [2024-02-15 11:48:47]
  • 提交

answer

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
	char ch=getchar();
	int f=1,x=0;
	while(ch<'0'||ch>'9'){
		if(ch=='-')
			f=-f;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	return f*x;
}
inline void work(int k){
	if(k<0){
		putchar('-');
		k=-k;
	}
	if(k>9)
		work(k/10);
	putchar(k%10+'0');
}
/*
现将dfs序搞下来变成一个序列
容易发现第一个满足前缀和>=sum/2的点一定在带权重心
直接倍增跳就行了
*/
int n,q,cnt,first[100005],siz[100005],son[100005],dep[100005],fa[100005],dp[100005],dfn[100005],rev[100005],num,dp1[100005][25];
struct q1{
	int u,w,nex;
}a[200005];
void add(int u1,int w1){
	a[++cnt]={u1,w1,first[u1]};
	first[u1]=cnt;
}
void dfs(int u,int dad){
	dp1[u][0]=dad;
	for(int i=1;i<=20;i++){
		dp1[u][i]=dp1[dp1[u][i-1]][i-1];
	}
	dep[u]=dep[dad]+1;
	fa[u]=dad;
	siz[u]=1;
	for(int i=first[u];i;i=a[i].nex){
		if(a[i].w==dad)
			continue;
		dfs(a[i].w,u);
		siz[u]+=siz[a[i].w];
		if(siz[son[u]]<siz[a[i].w])
			son[u]=a[i].w;
	}
}
void dfs1(int u,int t){
	dp[u]=t;
	dfn[u]=++num;
	rev[num]=u;
	if(son[u])
		dfs1(son[u],t);
	for(int i=first[u];i;i=a[i].nex){
		if(a[i].w==fa[u]||a[i].w==son[u])
			continue;
		dfs1(a[i].w,a[i].w);
	}
}
struct node{
	ll val[400005],lazy[400005];
	void pushdown(int k,int l,int r){
		int mid=(l+r)>>1;
		val[2*k]+=lazy[k]*(mid-l+1);
		val[2*k+1]+=lazy[k]*(r-mid);
		lazy[2*k]+=lazy[k];
		lazy[2*k+1]+=lazy[k];
		lazy[k]=0;
	}
	void change(int k,int l,int r,int x,int y,ll v){
		if(l>y||r<x)
			return ;
		if(l>=x&&r<=y){
			val[k]+=(r-l+1)*v;
			lazy[k]+=v;
			return ;
		}
		pushdown(k,l,r);
		int mid=(l+r)>>1;
		change(2*k,l,mid,x,y,v);
		change(2*k+1,mid+1,r,x,y,v);
		val[k]=val[2*k]+val[2*k+1];
	}
	ll query(int k,int l,int r,int x,int y){
		if(l>y||r<x)
			return 0;
		if(l>=x&&r<=y)
			return val[k];
		pushdown(k,l,r);
		int mid=(l+r)>>1;
		return query(2*k,l,mid,x,y)+query(2*k+1,mid+1,r,x,y);
	}
}tree;
int main(){
	n=read();
	for(int i=1,x,y;i<n;i++){
		x=read();
		y=read();
		add(x,y);
		add(y,x);
	}
	dfs(1,0);
	dfs1(1,1);
	q=read();
	while(q--){
		int f=read(),u=read(),v;
		if(f==1)
			tree.change(1,1,n,dfn[u],dfn[u]+siz[u]-1,1);
		else{
			v=read();
			int x=u,y=v;
			while(dp[x]!=dp[y]){
				if(dep[dp[x]]>dep[dp[y]])
					swap(x,y);
				tree.change(1,1,n,dfn[dp[y]],dfn[y],1);
				y=fa[dp[y]];
			}
			if(dep[x]>dep[y])
				swap(x,y);
			tree.change(1,1,n,dfn[x],dfn[y],1);
		}
		int l=1,r=n+1;
		ll sum=tree.query(1,1,n,1,n);
		while(l<r){
			int mid=(l+r)>>1;
			if(tree.query(1,1,n,1,mid)>sum/2.0)
				r=mid;
			else
				l=mid+1;
		}
		l=rev[l];
		// cerr<<l<<" "<<sum<<"\n";
		for(int i=20;i>=0;i--){
			int now=dp1[l][i];
			if(now&&tree.query(1,1,n,dfn[now],dfn[now]+siz[now]-1)<=sum/2.0)
				l=now;
		}
		if(sum==1)
			work(u);
		else
			work(dp1[l][0]);
		putchar('\n');
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 9772kb

input:

7
1 6
1 7
7 3
3 2
7 5
5 4
4
1 2
1 4
1 6
2 6 7

output:

2
7
7
1

result:

ok 4 lines

Test #2:

score: 0
Accepted
time: 1ms
memory: 7748kb

input:

15
1 2
1 3
2 4
3 7
6 2
3 8
4 9
2 5
5 11
7 13
10 4
11 15
12 5
14 7
11
2 6 11
1 6
2 10 9
1 9
2 2 6
1 4
2 7 6
1 2
2 8 13
1 10
2 8 15

output:

2
2
2
2
2
2
2
2
2
2
2

result:

ok 11 lines

Test #3:

score: 0
Accepted
time: 1ms
memory: 9780kb

input:

2
1 2
1
1 1

output:

1

result:

ok single line: '1'

Test #4:

score: 0
Accepted
time: 1ms
memory: 7812kb

input:

2
1 2
1
2 1 2

output:

1

result:

ok single line: '1'

Test #5:

score: -100
Wrong Answer
time: 6ms
memory: 7748kb

input:

100
1 2
58 2
2 87
63 87
65 63
65 19
6 87
58 21
87 8
87 74
91 6
95 65
2 61
87 59
3 61
37 87
67 87
23 2
63 9
87 46
40 67
70 2
12 58
46 75
75 36
28 3
12 33
72 87
39 6
75 52
85 70
1 76
26 40
47 28
2 49
41 65
66 28
51 37
15 47
86 51
8 60
97 19
48 58
72 90
33 83
97 54
36 5
23 14
78 52
90 7
99 2
48 82
48 6...

output:

87
3
3
87
87
2
2
2
2
87
87
87
87
87
2
87
87
87
87
87
87
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87
87...

result:

wrong answer 1st lines differ - expected: '72', found: '87'