珂学树过不了?大悲
查看原帖
珂学树过不了?大悲
100325
peterwuyihong楼主2021/7/29 11:35
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cerr<<#x<<' '<<x<<endl
/* --------------- fast io --------------- */ // begin
namespace Fread {
const int SIZE = 1 << 26;
char buf[SIZE], *S, *T;
inline char getchar() {
	if (S == T) {
		T = (S = buf) + fread(buf, 1, SIZE, stdin);
		if (S == T) return '\n';
	}
	return *S++;
}
} // namespace Fread
namespace Fwrite {
const int SIZE = 1 << 26;
char buf[SIZE], *S = buf, *T = buf + SIZE;
inline void flush() {
	fwrite(buf, 1, S - buf, stdout);
	S = buf;
}
inline void putchar(char c) {
	*S++ = c;
	if (S == T) flush();
}
struct NTR {
	~ NTR() { flush(); }
} ztr;
} // namespace Fwrite
#ifdef ONLINE_JUDGE
	#define getchar Fread :: getchar
	#define putchar Fwrite :: putchar
#endif
namespace Fastio {
struct Reader {
	template<typename T>
	Reader& operator >> (T& x) {
		char c = getchar();
		T f = 1;
		while (c < '0' || c > '9') {
			if (c == '-') f = -1;
			c = getchar();
		}
		x = 0;
		while (c >= '0' && c <= '9') {
			x = (x * 10 + (c - '0'));
			c = getchar();
		}
		x *= f;
		return *this;
	}
	Reader& operator >> (char& c) {
		c = getchar();
		while (c == '\n' || c == ' ') c = getchar();
		return *this;
	}
	Reader& operator >> (char* str) {
		int len = 0;
		char c = getchar();
		while (c == '\n' || c == ' ') c = getchar();
		while (c != '\n' && c != ' ') {
			str[len++] = c;
			c = getchar();
		}
		str[len] = '\0';
		return *this;
	}
	Reader(){}
} cin;
const char endl = '\n';
struct Writer {
	template<typename T>
	Writer& operator << (T x) {
		if (x == 0) { putchar('0'); return *this; }
		if (x < 0) { putchar('-'); x = -x; }
		static int sta[45];
		int top = 0;
		while (x) { sta[++top] = x % 10; x /= 10; }
		while (top) { putchar(sta[top] + '0'); --top; }
		return *this;
	}
	Writer& operator << (char c) {
		putchar(c);
		return *this;
	}
	Writer& operator << (char* str) {
		int cur = 0;
		while (str[cur]) putchar(str[cur++]);
		return *this;
	}
	Writer& operator << (const char* str) {
		int cur = 0;
		while (str[cur]) putchar(str[cur++]);
		return *this;
	}
	Writer(){}
} cout;
} // namespace Fastio
#define cin Fastio :: cin
#define cout Fastio :: cout
#define endl Fastio :: endl
/* --------------- fast io --------------- */ // end

#define maxn 100010
int n,m,T;
int x,y,op;
int dfn[maxn],top[maxn],cnt;
int fa[maxn],siz[maxn],son[maxn],dep[maxn];
int head[maxn],Next[maxn<<1],ver[maxn<<1],tot;
void add(int x,int y){
	ver[++tot]=y;
	Next[tot]=head[x];
	head[x]=tot;
}
void dfs1(int x){
	siz[x]=1;
	for(int i=head[x];i;i=Next[i]){
		int y=ver[i];
		if(dep[y])continue;
		dep[y]=dep[x]+1;
		fa[y]=x;
		dfs1(y);
		siz[x]+=siz[y];
		if(siz[son[x]]<siz[y])son[x]=y;
	}
}
void dfs2(int x,int t){
	dfn[x]=++cnt;
	top[x]=t;
	if(!son[x])return;
	dfs2(son[x],t);
	for(int i=head[x];i;i=Next[i])
	if(ver[i]!=fa[x]&&ver[i]!=son[x])dfs2(ver[i],ver[i]);
}
struct point{
	int l,r;
	mutable int v;
	point(int ll,int rr,int vv):l(ll),r(rr),v(vv){}
	bool inline operator<(point x)const{return l<x.l;}
};
#define Iter set<point>::iterator
set<point>s;
Iter split(int x){
	if(x>n)return s.end();
	Iter it=--s.upper_bound(point(x,0,0));
	if(it->l==x)return it;
	int l=it->l,r=it->r,v=it->v;
	s.erase(it);
	s.insert(point(l,x-1,v));
	return s.insert(point(x,r,v)).first;
}
void assign(int l,int r,int v){
	Iter itr=split(r+1),itl=split(l);
	s.erase(itl,itr);
	s.insert(point(l,r,v));
}
int ask(int k1,int l,int r,int k2){
	Iter itr=split(r+1),itl=split(l),tmp=itr;
	--tmp;
	assert(tmp!=itr);
	int ans=0;
	ans+=k2&&(tmp->v==k2);
	for(;itl!=itr;++itl){
		if(k1&&(k1==itl->v))ans++;
		if(itl->v)ans+=itl->r-itl->l;
		k1=itl->v;
	}
	return ans;
}
int get(int x){
	return s.lower_bound(point(x,0,0))->v;
}
void change(int x,int y,int col){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		assign(dfn[top[x]],dfn[x],col);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	assign(dfn[x],dfn[y],col);
}
int qry(int x,int y){
	int lx=0,ly=0;
	int ans=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y),swap(lx,ly);
		ans+=ask(0,dfn[top[x]],dfn[x],lx);
		lx=get(dfn[top[x]]);
//		cout<<"#"<<top[x]<<' '<<get(top[x])<<endl;
		x=fa[top[x]];
	}
//	cout<<"%"<<lx<<" "<<x<<' '<<ly<<" "<<y<<endl;
//	cout<<"@"<<ans<<endl;
	if(dep[x]>dep[y])swap(x,y),swap(lx,ly);
	ans+=ask(lx,dfn[x],dfn[y],ly);
	return ans;
}
signed main(){
#ifndef ONLINE_JUDGE
	freopen("edge5.in","r",stdin);
	freopen("testdata.out","w",stdout);
#endif
srand(time(NULL));
	for(cin>>T;T;T--){
		memset(head,0,sizeof head);
		s.clear();
		tot=1,cnt=0;
		memset(fa,0,sizeof fa);
		memset(dep,0,sizeof dep);
		memset(son,0,sizeof son);
		cin>>n>>m;
		s.insert(point(1,n,0));
		for(int i=1;i<n;i++){
			cin>>x>>y;
			add(x,y),add(y,x);
		}
		int rt=rand()%n+1;
		dep[rt]=1,dfs1(rt);
		dfs2(rt,rt);
	//	for(int i=1;i<=n;i++)cout<<dfn[i]<<' ';cout<<endl;
		while(m--){
			cin>>op>>x>>y;
			if(op==1)change(x,y,m);
			else cout<<qry(x,y)<<endl;
//			puts("Start");
//			for(Iter it=s.begin();it!=s.end();++it)cout<<it->l<<" "<<it->r<<' '<<it->v<<endl;
//			puts("End");
		}
	}
#ifndef ONLINE_JUDGE
	cerr<<endl<<(double)clock()/CLOCKS_PER_SEC;
#endif
}

TLE80\text{TLE80}珂朵莉爬树是真的慢草,主要是树链上切了太多链了,但还是想请dalaodalao卡常

2021/7/29 11:35
加载中...