(南昌邀请网络赛) J.Distance on the tree (树链剖分+主席树)

传送门

题意:给一颗树,m次查询ui->vi这条链中边权小于等于ki的边数。

解:树链剖分+主席树思路很清晰,可以解决;(又因为数组开小了而狂T不止

#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define SZ(a) int((a).size())
#define mid ((l+r)>>1)
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int N=2e5+5; 
template <typename _Tp> il void read(_Tp&x) {
	char ch;bool flag=0;x=0;
	while(ch=getchar(),!isdigit(ch)) if(ch=='-')flag=1;
	while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
	if(flag) x=-x;
}
//il int Add(ll &x,ll y) {return x=x+y>=mod?x+y-mod:x+y;}
//il int Mul(ll &x,ll y) {return x=x*y>=mod?x*y%mod:x*y;}
struct node{int to,w;};
vector<node> G[N];
int dep[N],fa[N],son[N],sz[N],ed[N],ned[N],id[N],bel[N],cnt;
il void dfs1(int x,int ff){
	dep[x]=dep[ff]+1;
	fa[x]=ff,sz[x]=1;
	int mx=-1,to,w,len=SZ(G[x]);
	node tp;
	for(int i=0;i<len;++i){
		tp=G[x][i],to=tp.to,w=tp.w;
		if(to==ff) continue;
		ed[to]=w;
		dfs1(to,x);
		sz[x]+=sz[to];
		if(sz[to]>mx) son[x]=to,mx=sz[to];
	}
} 
il void dfs2(int x,int topx){
	id[x]=++cnt,ned[cnt]=ed[x];
	bel[x]=topx;
	if(!son[x]) return;
	dfs2(son[x],topx);
	int to,len=SZ(G[x]);
	node tp;
	for(int i=0;i<len;++i){
		tp=G[x][i],to=tp.to;
		if(to==son[x] || to==fa[x]) continue;
		dfs2(to,to);
	}
} 
int n,m,b[N],tot=0,rt[N*20],ls[N*20],rs[N*20],s[N*20],all=0;
il void build(int &rt,int l,int r){
	rt=++tot,s[rt]=0;
	if(l==r) return;
	build(ls[rt],l,mid),build(rs[rt],mid+1,r);
} 
il void update(int &rt,int l,int r,int last,int p){
	rt=++tot,ls[rt]=ls[last],rs[rt]=rs[last];
	s[rt]=s[last]+1;
	if(l==r) return;
	if(p<=mid) update(ls[rt],l,mid,ls[last],p);
	else update(rs[rt],mid+1,r,rs[last],p);
}
il int query(int ss,int ee,int l,int r,int k){
	if(l==r) return s[ee]-s[ss];
	if(k>mid) return s[ls[ee]]-s[ls[ss]]+query(rs[ss],rs[ee],mid+1,r,k);
	else if(k==mid) return s[ls[ee]]-s[ls[ss]];
	else return query(ls[ss],ls[ee],l,mid,k);	
}
il int r_query(int x,int y,int k){
//	cout<<"r_query "<<x<<" "<<y<<" "<<k<<endl;
//	cout<<bel[x]<<" "<<bel[y]<<endl;
	int res=0;
	while(bel[x]!=bel[y]){
		if(dep[bel[x]]<dep[bel[y]]) swap(x,y);
		res+=query(rt[id[bel[x]]-1],rt[id[x]],1,all,k);
		x=fa[bel[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	res+=query(rt[id[x]],rt[id[y]],1,all,k);
	return res;
}
struct Q{
	int l,r,k;
}qu[N];
int main(){
//	std::ios::sync_with_stdio(0);cin.tie(0);
	read(n),read(m);
	int x,y,w,tt=0;
	for(int i=1;i<=n-1;++i){
		read(x),read(y),read(w);
		G[x].pb({y,w});
		G[y].pb({x,w});
		b[++tt]=w;
	}
	for(int i=1;i<=m;++i){
		read(x),read(y),read(w);
		qu[i]={x,y,w};
		b[++tt]=w;
	}
	dfs1(1,0),dfs2(1,1);
	b[++tt]=0;
	sort(b+1,b+tt+1);
	all=unique(b+1,b+tt+1)-(b+1);
	build(rt[0],1,all);
	for(int i=1;i<=n;++i){
		ned[i]=lower_bound(b+1,b+all+1,ned[i])-b;
		update(rt[i],1,all,rt[i-1],ned[i]);
	}
	for(int i=1;i<=m;++i){
		qu[i].k=lower_bound(b+1,b+all+1,qu[i].k)-b;
		printf("%d\n",r_query(qu[i].l,qu[i].r,qu[i].k));
	}
	return 0;
}








 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值