求助WA30
查看原帖
求助WA30
171487
cmll02楼主2021/6/2 12:17

RT不知道咋了

// Problem: P4689 [Ynoi2016] 这是我自己的发明
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4689
// Memory Limit: 512 MB
// Time Limit: 1500 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
#include <stdio.h>
#include <string.h> 
#include <algorithm>
#include <bitset>
#define od(x) printf("%lld",x)
#define odb(x) printf("%lld ",x)
#define odl(x) printf("%lld\n",x)
#define odp(x,y) printf("%d %d\n",x,y)
#define ol(x) puts("")
#define old(x) printf("%lld",x)
#define oldb(x) printf("%lld ",x)
#define oldl(x) printf("%lld\n",x)
#define oldp(x,y) printf("%lld %lld\n",x,y)
#define int long long
inline int read()
{
	int num=0,f=1;char c=getchar();
	while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
	while(c>47&&c<58)num=num*10+(c^48),c=getchar();
	return num*f;
}
inline int re1d()
{
	char c=getchar();
	while(c<48||c>49)c=getchar();
	return c&1;
}
inline int min(int a,int b){return a>b?b:a;}
inline int max(int a,int b){return a<b?b:a;}
const int B=555;
struct querys{
	int l,r,lb,i;
	bool operator<(const querys & b)const{return lb==b.lb?((lb&1)?r<b.r:r>b.r):lb<b.lb;}
}q[2000005];
struct Edge{
	int v,nxt;
}e[1000005];
typedef int arr[2000005];
arr dfn,lst,h,d,res;
int f[400005][20];
int cc,cnt=1;
inline void addedge(int u,int v)
{
	e[cnt]=(Edge){v,h[u]};
	h[u]=cnt++;
}
void dfs(int u,int fa)
{
	dfn[u]=++cc;
	d[u]=d[fa]+1;
	f[u][0]=fa;
	for(int i=1;i<19;i++)f[u][i]=f[f[u][i-1]][i-1];
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].v;
		if(v!=fa)dfs(v,u);
	}
	lst[u]=cc;
}
inline void ins(int root,int u,int& l,int& r,int n)
{
	if(root==u)
	{
		l=1,r=n;
		return;
	}
	if(dfn[u]<dfn[root]&&dfn[root]<=lst[u])
	{
		for(int i=18;i>=0;i--)if(d[root]-(1<<i)>d[u])root=f[root][i];
		// [ 1 , dfn[root] - 1 ] U [ lst[root] + 1 , n ]
		l=lst[root]+1,r=dfn[root]-1+n;
	}
	else l=dfn[u],r=lst[u];
}
arr a,b,c1,c2;int ans;
inline void addl(int x){c1[a[x]]++,ans+=c2[a[x]];}
inline void addr(int x){c2[a[x]]++,ans+=c1[a[x]];}
inline void rmvl(int x){c1[a[x]]--,ans-=c2[a[x]];}
inline void rmvr(int x){c2[a[x]]--,ans-=c1[a[x]];}
signed main()
{
	int n=read(),m=read();
	for(int i=1;i<=n;i++)a[i]=b[i]=read();
	std::sort(b+1,b+1+n);
	for(int i=1;i<=n;i++)a[i]=a[i+n]=std::lower_bound(b+1,b+n+1,a[i])-b;
	for(int i=1;i<n;i++){int u=read(),v=read();addedge(u,v);addedge(v,u);}
	dfs(1,0);
	int root=1;
	int cc=0,ccc=0;
	while(m--)
	{
		int op=read();
		if(op==1)root=read();
		else
		{
			int x=read(),y=read();
			int cl,cr,dl,dr;
			ins(root,x,cl,cr,n);
			ins(root,y,dl,dr,n);
			++cc;q[cc]=(querys){cr,dr,cr/B,cc};
			++cc;q[cc]=(querys){cr,dl-1,cr/B,cc};
			++cc;q[cc]=(querys){cl-1,dr,(cl-1)/B,cc};
			++cc;q[cc]=(querys){cl-1,dl-1,(cl-1)/B,cc};
			++ccc;
		}
	}
	std::sort(q+1,q+1+cc);
	int cl=0,cr=0;
	for(int i=1;i<=cc;i++)
	{
		int l=q[i].l,r=q[i].r;
		while(cl<l)addl(++cl);
		while(cr<r)addr(++cr);
		while(cr>r)rmvr(cr--);
		while(cl>l)rmvl(cl--);
		res[q[i].i]=ans;
	}
	for(int i=1;i<=ccc;i++)odl(res[i*4]+res[i*4-3]-res[i*4-1]-res[i*4-2]);
	return 0;
}
2021/6/2 12:17
加载中...