求助,树剖只过样例,交上去大红大紫还TLE
查看原帖
求助,树剖只过样例,交上去大红大紫还TLE
673643
GameFreak楼主2023/1/9 11:09

如题,求调。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
static char buf[1000000],*p1=buf,*p2=buf,obuf[1000000],*p3=obuf;
#define flush() fwrite(obuf,p3-obuf,1,stdout)
#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++
//#define putchar(x) (p3-obuf<1000000)?(*p3++=x):(flush(),p3=obuf,*p3++=x)
template<typename T> inline void read(T&);
template<typename T> inline void write(T);
template<typename... Args> inline void read(Args& ...);
template<typename... Args> inline void write(Args ...);
const int N=10005;
int n,m;
vector<int> G[N];
int col[N];
int dep[N],fa[N],siz[N],son[N],top[N],dfn[N],rnk[N],tot;
inline void dfs(int u){
	siz[u]=1,son[u]=-1;
	for(int v:G[u]){
		if(dep[v]) continue;
		fa[v]=u,dep[v]=dep[u]+1;
		dfs(v);
		siz[u]+=siz[v];
		if(son[u]==-1||siz[v]>siz[son[u]]) son[u]=v;
	}
}
inline void dfs(int u,int t){
	top[u]=t,rnk[dfn[u]=++tot]=u;
	if(son[u]!=-1) dfs(son[u],t);
	for(int v:G[u]) if(v!=fa[u]&&v!=son[u]) dfs(v,v);
}
class SegmentTree{
public:
	struct node{
		int sum,lc,rc,lazy;
		node():sum(0),lc(0),rc(0),lazy(0){}
	};
	node work(node l,node r){
		node ret=node();
		ret.sum=l.sum+r.sum-(l.rc==r.lc);
		ret.lc=l.lc,ret.rc=r.rc;
		return ret;
	}
private:
	node tr[N<<2];
	void push_down(const int& rt){
		if(!tr[rt].lazy) return;
		tr[rt<<1].sum=tr[rt<<1|1].sum=1;
		tr[rt<<1].lc=tr[rt<<1].rc=tr[rt<<1|1].lc=tr[rt<<1|1].rc=tr[rt].lazy;
		tr[rt<<1].lazy=tr[rt<<1|1].lazy;
		tr[rt].lazy=0;
	}
	void build(const int& rt,const int& l,const int& r){
		if(l==r){
			tr[rt].sum=1,tr[rt].lc=tr[rt].rc=tr[rt].lazy=col[rnk[l]];
			return;
		}
		const int mid=(l+r)>>1;
		build(rt<<1,l,mid),build(rt<<1|1,mid+1,r);
		tr[rt]=work(tr[rt<<1],tr[rt<<1|1]);
	}
	void updata(const int& rt,const int& l,const int& r,const int& L,const int& R,const int& val){
		if(L<=l&&r<=R){
			tr[rt].sum=1,tr[rt].lc=tr[rt].rc=tr[rt].lazy=val;
			return;
		}
		push_down(rt);
		const int mid=(l+r)>>1;
		if(L<=mid) updata(rt<<1,l,mid,L,R,val);
		if(R>mid) updata(rt<<1|1,mid+1,r,L,R,val);
		tr[rt]=work(tr[rt<<1],tr[rt<<1|1]);
	}
	node query(const int& rt,const int& l,const int& r,const int& L,const int& R){
		if(L<=l&&r<=R) return tr[rt];
		push_down(rt);
		const int mid=(l+r)>>1;
		if(L<=mid&&R>mid) return work(query(rt<<1,l,mid,L,R),query(rt<<1|1,mid+1,r,L,R));
		return L<=mid?query(rt<<1,l,mid,L,R):query(rt<<1|1,mid+1,r,L,R);
	}
public:
	SegmentTree(){}
	void build(){build(1,1,n);}
	void updata(int L,int R,int val){updata(1,1,n,L,R,val);}
	node query(int L,int R){return query(1,1,n,L,R);}
};
SegmentTree tr;
void updata(int u,int v,int col){
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		tr.updata(dfn[top[u]],dfn[u],col);
		u=fa[top[u]];
	}
	if(dfn[u]>dfn[v]) swap(u,v);
	tr.updata(dfn[u],dfn[v],col);
}
int query(int u,int v){
	int ret=0,ul=0,vl=0;
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]) swap(u,v),swap(ul,vl);
		SegmentTree::node now=tr.query(dfn[top[u]],dfn[u]);
		ret+=now.sum-(now.rc==ul),ul=now.lc,u=fa[top[u]];
	}
	if(dfn[u]>dfn[v]) swap(u,v);
	SegmentTree::node now=tr.query(dfn[u],dfn[v]);
	return ret+now.sum-(now.lc==ul)-(now.rc==vl);
}
inline void solve(char opt=getchar(),int u=0,int v=0,int w=0){
	while(opt==' '||opt=='\n') opt=getchar();
	switch(opt){
		case 'C':
			read(u,v,w);
			updata(u,v,w);
			break;
		case 'Q':
			read(u,v);
			write(query(u,v),'\n');
			break;
	}
}
signed main(){
//	freopen("1.txt","r",stdin);
	read(n,m);
	for(int i=1;i<=n;i++) read(col[i]);
	for(int i=1,u,v;i<n;i++){
		read(u,v);
		G[u].emplace_back(v),G[v].emplace_back(u);
	}
	dep[1]=1,dfs(1),dfs(1,1);
	tr.build();
	for(;m--;) solve();
	flush();
	return 0;
}

template<typename T> inline void read(T& x){
	x=0;bool flag=0;char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') flag=1;
	if(flag) for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)-(ch&15);
	else for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch&15);
}
template<typename T> inline void write(T x){
    static int sta[40];
    int top=0;
    if(x<0){
        putchar('-');
        do sta[top++]=(-x)%10,x/=10;
        while(x);
    }
    else{
        do sta[top++]=x%10,x/=10;
        while(x);
    }
    while(top) putchar(sta[--top]^48);
}
template<> inline void write(char x){putchar(x);}
template<typename... Args> inline void read(Args& ...args){(void)initializer_list<int>{(read(args),0)...};}
template<typename... Args> inline void write(Args ...args){(void)initializer_list<int>{(write(args),0)...};}
2023/1/9 11:09
加载中...