P7735求调
  • 板块学术版
  • 楼主_RON_
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/12/21 15:02
  • 上次更新2023/12/21 16:13:59
查看原帖
P7735求调
1127258
_RON_楼主2023/12/21 15:02

我一开始以为TLE是因为数剖常数太大了,没想到深层递归爆缓存了求调(orz)

#include <bits/stdc++.h>
using namespace std;
struct node {
	long long l, r;
	long long cnt;
	long long tag; 
};
node tree[5000001];
void make(long long i, long long l, long long r, long long x, long long y, long long k) {
	if(tree[i].tag&&l!=r) {
		make(i*2,l,(l+r)>>1,l,(l+r)>>1,tree[i].tag);
		make(i*2+1,((l+r)>>1)+1,r,((l+r)>>1)+1,r,tree[i].tag);
		tree[i].cnt=r-l;
		tree[i].tag=0;
	}
	if (l == x && r == y) {
		tree[i].l = k;
		tree[i].r = k;
		tree[i].cnt = r - l;
		tree[i].tag = k;
		return;
	}
	long long mid = (l + r) >> 1;
	if (mid >= y) {
		make(i * 2, l, mid, x, y, k);
		if (y == mid)
			tree[i].l = k;
		tree[i].cnt = tree[i * 2].cnt + tree[i * 2 + 1].cnt+(tree[i].l==tree[i].r&&tree[i].l);
		
	} else {
		if (mid + 1 <= x) {
			make(i * 2 + 1, mid+1, r, x, y, k);
			if (x == mid + 1)
				tree[i].r = k;
			tree[i].cnt = tree[i * 2].cnt + tree[i * 2 + 1].cnt+(tree[i].l==tree[i].r&&tree[i].l);
		} else {
			make(i * 2, l, mid, x, mid, k);
			make(i * 2 + 1, mid + 1, r, mid + 1, y, k);
			tree[i].l = k;
			tree[i].r = k;
			tree[i].cnt = tree[i * 2].cnt + tree[i * 2 + 1].cnt + 1;
		}
	}
}
long long anwser(long long i, long long l, long long r, long long x, long long y) {
	if(tree[i].tag&&l!=r) {
		make(i*2,l,(l+r)>>1,l,(l+r)>>1,tree[i].tag);
		make(i*2+1,((l+r)>>1)+1,r,((l+r)>>1)+1,r,tree[i].tag);
		tree[i].l = tree[i].tag;
		tree[i].r = tree[i].tag;
		tree[i].cnt = tree[i * 2].cnt + tree[i * 2 + 1].cnt + 1;
		tree[i].tag=0;
	}
	if (l == x && r == y) 
		return tree[i].cnt;
	long long mid = (l + r) >> 1;
	if (mid >= y) {
		return anwser(i * 2, l, mid, x, y);
	} else {
		if (mid + 1 <= x) {
			return anwser(i * 2 + 1, mid+1, r, x, y);
		} else {
			return anwser(i * 2, l, mid, x, mid) + anwser(i * 2 + 1, mid + 1, r, mid + 1, y) + (tree[i].l == tree[i].r&&tree[i].l);
		}
	}
}
long long find(long long i,long long l,long long r,long long x) {
	if(tree[i].tag&&l!=r) {
		tree[i].cnt=r-l;
		make(i*2,l,(l+r)>>1,l,(l+r)>>1,tree[i].tag);
		make(i*2+1,((l+r)>>1)+1,r,((l+r)>>1)+1,r,tree[i].tag);
		tree[i].l = tree[i].tag;
		tree[i].r = tree[i].tag;
		tree[i].cnt = tree[i * 2].cnt + tree[i * 2 + 1].cnt + 1;
		long long temp=tree[i].tag;
		tree[i].tag=0;
		return temp;
	}
	if (l == r)
		return tree[i].tag;
	long long mid = (l + r) >> 1;
	if (mid >= x) {
		return find(i * 2, l, mid,x);
	} else {
		return find(i * 2 + 1, mid+1, r, x);
	}
} 
vector<long long>edge[100001];
long long cnt, ids[100001], top[100001], dep[100001], fa[100001], sum[100001], son[100001];
inline void dfs1(long long o, long long fas, long long dp) {
	dep[o] = dp;
	fa[o] = fas;
	sum[o] = 1;
	int bison = -100000000;
	for (int i = 0; i < edge[o].size(); i++) {
		long long y = edge[o][i];
		if (y == fas)
			continue;
		dfs1(y, o, dp + 1);
		sum[o] += sum[y];
		if (sum[y] > bison)
			son[o] = y, bison = sum[y];
	}
}
void dfs2(long long o, long long fas) {
	ids[o] = ++cnt;
	top[o] = fas;
	if (!son[o])
		return;
	dfs2(son[o], fas);
	for (int i = 0; i < edge[o].size(); i++) {
		long long t = edge[o][i];
		if (t == fa[o] || t == son[o])
			continue;
		dfs2(t, t);
	}
}
long long n, m;
void do1(long long a, long long b, long long c) {
	while (top[a] != top[b]) {
		if (dep[top[a]] < dep[top[b]])
			swap(a, b);
		make(1,1,n, ids[top[a]], ids[a], c);
		a = fa[top[a]];
	}
	if (ids[a] > ids[b])
		swap(a, b);
	make(1, 1,n,ids[a], ids[b], c);
}
long long do2(long long a, long long b) {
	long long ans = 0,jjja=0,jjjb=0;
	while (top[a] != top[b]) {
		if (dep[top[a]] < dep[top[b]]) {
			ans+=anwser(1,1,n,ids[top[b]],ids[b]);
			long long temp=find(1,1,n,ids[top[b]]);
			if(temp==find(1,1,n,ids[fa[top[b]]])&&temp)	
				ans++;
			b=fa[top[b]];
		} else {
			ans += anwser(1, 1, n, ids[top[a]], ids[a]);
			long long temp=find(1,1,n,ids[top[a]]);
			if(temp==find(1,1,n,ids[fa[top[a]]])&&temp)
				ans++;
			a = fa[top[a]];
		}
	}
	if (dep[a] > dep[b])
		swap(a, b);
	return ans + anwser(1, 1, n, ids[a], ids[b]);
}
int main() {
 	freopen("P7735_7.in","r",stdin);
//	freopen("edge2.out","w",stdout);
	long long s;
	cin >> s;
	for (int fds = 1; fds <= s; fds++) {
		cin >> n >> m;
		for (int j = 1; j < n; j++) {
			long long ccf,fuck;
			scanf("%lld%lld",&ccf,&fuck);
			edge[fuck].push_back(ccf);
			edge[ccf].push_back(fuck);
		}
		dfs1(1, 1, 1);
		dfs2(1, 1);
		for (int i = 1; i <= m; i++) {
			long long op, a, b;
			scanf("%lld%lld%lld",&op,&a,&b);
			if (op == 1)
				do1(a, b,i);
			else
				printf("%lld\n",do2(a,b));
		}
		for(int i=1;i<=100000;i++)
			edge[i].clear(),cnt=ids[i]=top[i]=dep[i]=fa[i]=sum[i]=son[i]=0;
		for(int i=1;i<=400000;i++)
			tree[i].cnt=tree[i].l=tree[i].r=tree[i].tag=0;
		cnt=0;
	}
	return 0;
}
2023/12/21 15:02
加载中...