首页 > 其他分享 >树论(一)

树论(一)

时间:2024-08-07 14:06:22浏览次数:5  
标签:cnt 1000005 return int 树论 t1 dep

  • 在“无限”的量中寻找“有限”的量——可能产生贡献的点对的数量
  • 不妨用两个log的时间复杂度进行预处理(都预处理了,就不要再想着判断合法性了)
  • 1~N每个数的约数个数的总和大约为NlogN
  • u,v都在某个子树内等价于它们的【最近公共祖先】在该子树内,将点对的贡献打到LCA(i,j)上
点击查看代码
#include <bits/stdc++.h>
using namespace std;
vector<int>a[1000005];
vector<int>d[100005];
int dep[1000005],s[1000005],n,tot,dfn[1000005],c[1000005];
int f[1000005][20];
int ans[1000005];
int lca(int u,int v)
{
    if(dep[u]>dep[v])
    {
        swap(u,v);
    }
    for(int j=19;j>=0;j--)
    {
        if(f[v][j]!=0&&dep[f[v][j]]>=dep[u])
        {
            v=f[v][j];
        }
    }
    if(u==v)
    {
        return u;
    }
    for(int j=19;j>=0;j--)
    {
        if(f[u][j]!=f[v][j])
        {
            u=f[u][j];
            v=f[v][j];
        }
    }
    return f[u][0];
}
void pre()
{
    for(int j=1;j<20;j++)
    {
        for(int i=1;i<=n;i++)
        {
            f[i][j]=f[f[i][j-1]][j-1];
        }
    }
}
void dfs(int n1)
{
	dfn[n1]=++tot;
	s[n1]=1;
    for(int i=0;i<a[n1].size();i++)
    {
    	if(a[n1][i]!=f[n1][0])
    	{
	        dep[a[n1][i]]=dep[n1]+1;
	        f[a[n1][i]][0]=n1;
	        dfs(a[n1][i]);
	        s[n1]+=s[a[n1][i]];
	    }
    }
}
int lowbit(int n)
{
	return n&(-n);
}
void add(int n1)
{
	while(n1<=n)
	{
		c[n1]++;
		n1+=lowbit(n1);
	}
}
int ask(int n1)
{
	int s=0;
	while(n1>0)
	{
		s+=c[n1];
		n1-=lowbit(n1);
	}
	return s;
}
int gcd(int a,int b)
{
	if(b==0)
	{
		return a;
	}
	return gcd(b,a%b);
}
int lcm(int a,int b)
{
	return a/gcd(a,b)*b;
}
struct t1
{
	int i,j,l;
}t[3000005];
int cnt;
bool cmpt(t1 a,t1 b)
{
	return a.l<b.l;
}
struct q1
{
	int r,x,id;
}q[1000005];
bool cmpq(q1 a,q1 b)
{
	return a.x<b.x;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	for(int i=1;i<=100000;i++)
	{
		for(int j=i;j<=100000;j+=i)
		{
			d[j].push_back(i); 
		}
	}
	int T;
	cin>>T;
	while(T--)
	{
		memset(c,0,sizeof(c));
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			a[i].clear();
		}
		for(int i=1;i<n;i++)
		{
			int u,v;
			cin>>u>>v;
			a[u].push_back(v);
			a[v].push_back(u);
		}
		tot=0;
		dep[1]=1;
		dfs(1);
		pre();
		cnt=0;
		for(int i=1;i<=n;i++)
		{
			for(int l=i;l<=100000;l+=i)
			{
				for(int j=0;j<d[l].size();j++)
				{
					if(d[l][j]>i)
					{
						break;
					}
					if(lcm(i,d[l][j])==l)
					{
						t[++cnt]=(t1){i,d[l][j],l};
					}
				}
			}
		}
		sort(t+1,t+cnt+1,cmpt);
		int Q;
		cin>>Q;
		for(int i=1;i<=Q;i++)
		{
			cin>>q[i].r>>q[i].x;
			q[i].id=i;
		}
		sort(q+1,q+Q+1,cmpq);
		int p=0;
		for(int i=1;i<=Q;i++)
		{
			while(p+1<=cnt&&t[p+1].l<=q[i].x)
			{
				p++;
				int tmp=lca(t[p].i,t[p].j);
				add(dfn[tmp]);
				if(t[p].i!=t[p].j)
				{
					add(dfn[tmp]);
				}
			}
			ans[q[i].id]=ask(dfn[q[i].r]+s[q[i].r]-1)-ask(dfn[q[i].r]-1);
		}
		for(int i=1;i<Q;i++)
		{
			cout<<ans[i]<<' ';
		}
		cout<<ans[Q]<<endl;
	}
	return 0;
}

标签:cnt,1000005,return,int,树论,t1,dep
From: https://www.cnblogs.com/watersail/p/18346929

相关文章

  • 7.15 树论
    MilkVisitsG自己做出来哒!先考虑是一条链时怎么做。很显然,用set维护每种奶的位置,然后lowerbound查找\(l\)再判断是否合法即可。那么再放到树上来做,显然,直接树链剖分就可以把树转化成链。于是做完力!点击查看代码#include<bits/stdc++.h>usingnamespacestd;constintN......
  • 【树论典题】P5642 人造情感(emotion)
    P5642人造情感(emotion)随便挑点杂题做/kk。乐。不会做这个题,我难道还不会做CF856DMashaandCactus。先考虑后者怎么做?CF856DMashaandCactus乐。考虑在\(LCA\)上挂很多个chains.\[s_u=\sum_{v\inson_u}f_v,f_u=s_u\]\[t_i=\underset{(x_i,y_i,w_i)}......
  • 【树论】RMQ问题和ST表
    目录RMQ问题ST表优缺点实现递推查询复杂度代码技巧-快速读入RMQ问题RMQ(RangeMaximum/MinimumQuery)问题,即区间最值问题。一般是多次询问,对时间复杂度要求高,一般需要\(O(logn)\)或\(O(1)\)复杂度ST表p[i][j]是以i为起点,连续\(2^j\)个数字的最大值(是一个递推表)3......
  • 简单树论
    cmd的blog可以参考水平不高,内容比较简单.内容难度不随章节单增.0.杂七杂八做题做到什么东西都会扔到这里.想到啥写啥.如果要求统计树上所有点对之间的贡献,可以考虑枚举lca.(CF1856E1)如果有类似于树上经过的边的权值\(\leqk\)这样的限制,可以把边按照边......
  • 【树论,计数】Centroid Probabilities
    生生动动贺题贺一遍!考虑先求出\(f_x\)表示\(x\)子树大小\(\leq\frac{n+1}{2}\)的方案数。最后再容斥掉\(x+1\ton\)的方案即可。\[\sum^{n-x+1}_{j=\frac{n+1}{2}}\binom{n-i}{j-1}(j-1)!(n-j-1)!(i-1)\]即考虑选出子树,生成子树内和子树......
  • 【树论典题。】P6071 『MdOI R1』Treequery
    前言:输了,被水杯提醒我一直很失败。正片:简要题意求\([l,r]\top\)的路径的交的边权和。Solution:\(O(n\log^2n)\)巨大分讨做法。考虑分类讨论。其一,\(p\)根本就不属于路径上的点,这个求区间LCA可以解决\(p\toanc_{[l,r]}\)其二,\(p\)是\(anc_{l,r}\)的祖......
  • 7.27 day4 树论
    悲报:335->220战绩:100+100+20+0T1求子树sizeT2通过大眼观察严谨的证明后,我们发现\(x_i\)是\(x_i+1\)的祖先的概率和\(x_i+1\)具体是什么无关:我们令\(x_i+1\)一直跳父亲,直到编号小于等于\(x_i\)的那一次。因为父亲是等概率选取的,所以概率就是\(\frac{1}{x_i}\)......
  • 树论
    1.重链剖分1.1.简介重链剖分将树分割成若干链维护信息,将树的结构转换为线性结构,然后可用其他数据结构维护。定义以下概念:重子节点轻子节点重边轻边重链某节点的子节点中子树大小最大的那个某节点的子节点中的非重子节点由某节点到其重子节点的连边由某节点到......
  • 树论汇总
    一、最近公共祖先最近公共祖先二、树链剖分重链剖分长链剖分三、树分治点分治点分树四、计数问题Prufer序列......
  • 树论 基础
    本文包含树的定义,树的存储,树的遍历(包括定义,求法).基础定义我们把\(n\)个点,\(n-1\)条边的图称为树.特别情况对于树,存在部分情况,使其有着特殊的性质......