【圆方树】CodeForces487E Tourists

分析:

圆方树板子题。

每个点方点放个multiset维护其子圆点的最小值

询问和修改用树剖

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#define SF scanf
#define PF printf
#define MAXN 200010
#define INF 0x3FFFFFFF
using namespace std;
typedef pair<int,int> pii;
struct node{
	int u,v;
	node () {}
	node (int u1,int v1):u(u1),v(v1) {}	
}Edge[MAXN];
int dfn[MAXN],low[MAXN],cnt;
vector<int> a[MAXN];
int st[MAXN],tp,n2,tot;
void dfs(int x,int fa=0){
	dfn[x]=low[x]=++cnt;	
	st[++tp]=x;
	for(int i=0;i<int(a[x].size());i++){
		int u=a[x][i];
		if(u==fa)
			continue;
		if(dfn[u]==0){
			dfs(u,x);
			low[x]=min(low[x],low[u]);
			if(low[u]>=dfn[x]){
				n2++;
				Edge[++tot]=node(n2,x);
				while(1){
					Edge[++tot]=node(n2,st[tp]);
					if(st[tp--]==u)
						break;	
				}
			}
		}
		else
			low[x]=min(low[x],dfn[u]);
	}
}
multiset<int> val[MAXN];
int son[MAXN],siz[MAXN];
int w[MAXN],n;
void prepare(int x,int fa=0){
	if(fa>n)
		val[fa].insert(w[x]);
	siz[x]=1;
	for(int i=0;i<int(a[x].size());i++){
		int u=a[x][i];
		if(u==fa)
			continue;
		prepare(u,x);	
		siz[x]+=siz[u];
		if(son[x]==0||siz[son[x]]<siz[u])
			son[x]=u;
	}
}
int tpd[MAXN];
int rk[MAXN],faz[MAXN],dep[MAXN];
void build_tree(int x,int tpx,int fa=0){
	tpd[x]=tpx;
	faz[x]=fa;
	dfn[x]=++cnt;
	dep[x]=dep[fa]+1;
	rk[cnt]=x;
	if(son[x]){
		build_tree(son[x],tpx,x);
		for(int i=0;i<int(a[x].size());i++){
			int u=a[x][i];
			if(u==fa||u==son[x])
				continue;
			build_tree(u,u,x);
		}
	}
}
int tree[MAXN*4];
void build(int id,int l,int r){
	if(l==r){
		if(rk[l]<=n)
			tree[id]=w[rk[l]];
		else
			tree[id]=*val[rk[l]].begin();
		return ;
	}
	int mid=(l+r)>>1;
	build(id<<1,l,mid);
	build(id<<1|1,mid+1,r);
	tree[id]=min(tree[id<<1],tree[id<<1|1]);
}
void update(int id,int l,int r,int pos){
	if(l==r){
		if(rk[l]<=n)
			tree[id]=w[rk[l]];
		else
			tree[id]=*val[rk[l]].begin();
		return ;
	}
	int mid=(l+r)>>1;
	if(pos<=mid)
		update(id<<1,l,mid,pos);
	else
		update(id<<1|1,mid+1,r,pos);
	tree[id]=min(tree[id<<1],tree[id<<1|1]);
}
int ask(int id,int l,int r,int pl,int pr){
	if(l>=pl&&r<=pr)
		return tree[id];
	int mid=(l+r)>>1;
	int res=INF;
	if(pl<=mid)
		res=ask(id<<1,l,mid,pl,pr);
	if(pr>mid)
		res=min(res,ask(id<<1|1,mid+1,r,pl,pr));
	return res;
}
pii query(int u,int v){
	if(dep[tpd[u]]<dep[tpd[v]]||(dep[tpd[u]]==dep[tpd[v]]&&dep[u]<dep[v]))
		swap(u,v);
	if(tpd[u]==tpd[v])
		return make_pair(ask(1,1,n2,dfn[v],dfn[u]),v);
	pii res=query(faz[tpd[u]],v);
	res.first=min(res.first,ask(1,1,n2,dfn[tpd[u]],dfn[u]));
	return res;
}
char s[20];
int main(){
	int m,q,u,v;
	SF("%d%d%d",&n,&m,&q);
	for(int i=1;i<=n;i++)
		SF("%d",&w[i]);
	for(int i=1;i<=m;i++){
		SF("%d%d",&u,&v);
		a[u].push_back(v);
		a[v].push_back(u);
	}
	n2=n;
	dfs(1);
	for(int i=1;i<=n;i++)
		a[i].clear();
	for(int i=1;i<=tot;i++){
//		PF("[%d %d]\n",Edge[i].u,Edge[i].v);
		a[Edge[i].u].push_back(Edge[i].v);
		a[Edge[i].v].push_back(Edge[i].u);
	}
	prepare(1);
	cnt=0;
	build_tree(1,1);
	build(1,1,n2);
	for(int i=1;i<=q;i++){
		SF("%s",&s);	
		if(s[0]=='A'){
			SF("%d%d",&u,&v);
			pii res=query(u,v);
			int x=res.second;
			int ans=res.first;
			if(x>n)
				ans=min(ans,w[faz[x]]);
			PF("%d\n",ans);
		}
		else{
			SF("%d%d",&u,&v);
			if(faz[u]>n){
				val[faz[u]].erase(val[faz[u]].find(w[u]));
				w[u]=v;
				val[faz[u]].insert(w[u]);
				update(1,1,n2,dfn[faz[u]]);
			}
			w[u]=v;
			update(1,1,n2,dfn[u]);
		}
	}
}
基于数据挖掘的音乐推荐系统设计与实现 需要一个代码说明,不需要论文 采用python语言,django框架,mysql数据库开发 编程环境:pycharm,mysql8.0 系统分为前台+后台模式开发 网站前台: 用户注册, 登录 搜索音乐,音乐欣赏(可以在线进行播放) 用户登陆时选择相关感兴趣的音乐风格 音乐收藏 音乐推荐算法:(重点) 本课题需要大量用户行为(如播放记录、收藏列表)、音乐特征(如音频特征、歌曲元数据)等数据 (1)根据用户之间相似性或关联性,给一个用户推荐与其相似或有关联的其他用户所感兴趣的音乐; (2)根据音乐之间的相似性或关联性,给一个用户推荐与其感兴趣的音乐相似或有关联的其他音乐。 基于用户的推荐和基于物品的推荐 其中基于用户的推荐是基于用户的相似度找出相似相似用户,然后向目标用户推荐其相似用户喜欢的东西(和你类似的人也喜欢**东西); 而基于物品的推荐是基于物品的相似度找出相似的物品做推荐(喜欢该音乐的人还喜欢了**音乐); 管理员 管理员信息管理 注册用户管理,审核 音乐爬虫(爬虫方式爬取网站音乐数据) 音乐信息管理(上传歌曲MP3,以便前台播放) 音乐收藏管理 用户 用户资料修改 我的音乐收藏 完整前后端源码,部署后可正常运行! 环境说明 开发语言:python后端 python版本:3.7 数据库:mysql 5.7+ 数据库工具:Navicat11+ 开发软件:pycharm
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值