• Ynoi2016 这是我自己发明的


    Description

    link

    支持换根和给定两个点,求子树中满足权值相同的方案数

    Solution

    遥远的国度 (+) 一个简单的询问

    (上面两个都是题目名称)

    推荐卡常数技巧:把没有用的询问都删掉(就是(l_1,l_2)(1)(0) 比关系的时候)

    别的不用stl或者不用函数,手写一类的不大好使(蒟蒻的个人经历)

    Code

    #include<bits/stdc++.h>
    using namespace std;
    namespace yspm{
    	inline int read()
    	{
    		int res=0,f=1; char k;
    		while(!isdigit(k=getchar())) if(k=='-') f=-1;
    		while(isdigit(k)) res=res*10+k-'0',k=getchar();
    		return res*f;
    	}
    	const int N=5e5+10;
    	int a[N],b[N],m,n,T,bl[N],fa[N][25],dep[N],st[N],ed[N],head[N],cnt,tot,dfn,block,ans[N*5],p[N];
    	struct node{
    		int nxt,to;
    	}e[N<<1];
    	inline void add(int u,int v)
    	{
    		e[++cnt].nxt=head[u]; e[cnt].to=v; head[u]=cnt;
    		return ;
    	}
    	inline void dfs(int x,int fat)
    	{
    		dep[x]=dep[fat]+1; st[x]=++dfn; fa[x][0]=fat; p[dfn]=x;
    		for(int i=1;(1<<i)<=dep[x];++i) fa[x][i]=fa[fa[x][i-1]][i-1];
    		for(int i=head[x];i;i=e[i].nxt) if(e[i].to==fat) continue; else dfs(e[i].to,x);
    		ed[x]=dfn;
    		return ;
    	}
    	struct ask{
    		int l,r,fl,id;
    		inline void init(int a,int b,int c,int d){l=a,r=b,fl=c,id=d; return ;}
    		bool operator <(const ask &x) const
    		{
    			if(bl[l]!=bl[x.l]) return l<x.l;
    			if(bl[l]&1) return r<x.r;
    			return r>x.r;
    		}
    	}q[N*16];
    	int res,l=0,r=0,s1[N],s2[N],opt,rt=1,num;
    	inline void add1(int x)
    	{
    		s1[x]++; res+=s2[x];
    		return ;
    	}
    	inline void del1(int x)
    	{
    		s1[x]--; res-=s2[x];
    		return ;
    	}
    	inline void del2(int x)
    	{
    		s2[x]--; res-=s1[x];
    		return ;
    	}
    	inline void add2(int x)
    	{
    		s2[x]++; res+=s1[x];
    		return ;
    	}
    	int t1[10],t2[10],now,sz,x,y;
    	inline void calc(int x)
    	{
    		if(x==rt) 
    		{
    			t1[++now]=1,t2[now]=n;
    		}
    		else if(!(st[x]<=st[rt]&&ed[rt]<=ed[x])) 
    		{
    			t1[++now]=st[x]; t2[now]=ed[x];
    		}
    		else
    		{
    			int p=dep[rt]-dep[x]-1,y=rt;
    			for(int i=0;i<18;++i) 
    			{
    				if(p&(1<<i)) y=fa[y][i];
    			} 
    			t1[++now]=1; t2[now]=st[y]-1;
    			t1[++now]=ed[y]+1; t2[now]=n;
    		}return ;
    	}
    	#define l1 t1[i]
    	#define l2 t1[j]
    	#define r1 t2[i]
    	#define r2 t2[j]
    	signed main()
    	{
    		n=read(); T=read(); block=sqrt(n);
    		for(int i=1;i<=n;++i) bl[i]=(i-1)/block+1,a[i]=read(),b[++m]=a[i];
    		sort(b+1,b+m+1); m=unique(b+1,b+m+1)-b-1;
    		for(int i=1;i<=n;++i) a[i]=lower_bound(b+1,b+m+1,a[i])-b;
    		for(int i=1,u,v;i<n;++i) u=read(),v=read(),add(u,v),add(v,u);
    		dfs(1,0);
    		while(T--)
    		{
    			opt=read();
    			if(opt==1) rt=read();
    			else
    			{
    				x=read(),y=read(); ++num; now=0; calc(x); sz=now; calc(y);
    				for(int i=1;i<=sz;++i) 
    				{
    					for(int j=sz+1;j<=now;++j) 
    					{
    						if(l1>r1||l2>r2||l1<1||l2<1||r2>n||l2>n) continue; 
    						if(l1>1&&l2>1) q[++tot].fl=1,q[tot].id=num,q[tot].l=l1-1,q[tot].r=l2-1;
    						q[++tot].fl=1; q[tot].id=num; q[tot].l=r1; q[tot].r=r2;
    						if(l1>1) q[++tot].fl=-1,q[tot].id=num,q[tot].r=r2,q[tot].l=l1-1;
    						if(l2>1) q[++tot].fl=-1,q[tot].id=num,q[tot].r=r1,q[tot].l=l2-1;
    					}
    				}
    			} 
    		}
    		for(int i=1;i<=tot;++i) if(q[i].l>q[i].r) swap(q[i].l,q[i].r);
    		sort(q+1,q+tot+1);
    		for(int i=1;i<=tot;++i)
    		{
    			while(l<q[i].l) ++l,add1(a[p[l]]);
    			while(l>q[i].l) del1(a[p[l]]),--l;
    			while(r<q[i].r) ++r,add2(a[p[r]]);
    			while(r>q[i].r) del2(a[p[r]]),--r;
    			ans[q[i].id]+=q[i].fl*res;
    		} 
    		for(int i=1;i<=num;++i) printf("%d
    ",ans[i]);
    		return 0;
    	}
    }
    signed main(){return yspm::main();}
    
  • 相关阅读:
    模型命名规范
    Jquery 将表单序列化为Json对象
    Failed to read auto-increment value from storage engine错误的处理方法
    css样式表中设置table的第一列的宽度是固定值
    thinkphp中I("parm")用法的注意事项
    获取凌晨00:00:00的时间
    php empty()和isset()的区别
    react续集
    react的笔记整理
    vuex
  • 原文地址:https://www.cnblogs.com/yspm/p/13236817.html
Copyright © 2020-2023  润新知