zoukankan      html  css  js  c++  java
  • 【BZOJ4372】烁烁的游戏(动态点分治)

    【BZOJ4372】烁烁的游戏(动态点分治)

    题面

    BZOJ
    大意:
    每次在一棵书上进行操作
    1.将离某个点u的距离不超过d的点的权值加上w
    2.询问单点权值

    题解

    这题和前面那一道震波几乎是一模一样的
    只不过把两个操作的区间问题给换了一下
    现在是区间修改,单点询问而已

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define MAX 120000
    inline int read()
    {
    	int x=0,t=1;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=-1,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return x*t;
    }
    struct Line{int v,next;}e[MAX<<1],E[MAX<<1];
    int h[MAX],cnt=1;
    inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
    /************************************************************************/
    int dfn[MAX],top[MAX],dep[MAX],ssize[MAX],hson[MAX],fa[MAX];
    int dis[MAX];
    void dfs1(int u,int ff)
    {
    	fa[u]=ff;ssize[u]=1;dep[u]=dep[ff]+1;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;
    		if(v==ff)continue;
    		dfs1(v,u);
    		ssize[u]+=ssize[v];
    		if(ssize[hson[u]]<ssize[v])hson[u]=v;
    	}
    }
    void dfs2(int u,int tp)
    {
    	top[u]=tp;
    	if(hson[u])dfs2(hson[u],tp);
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;
    		if(v==fa[u]||v==hson[u])continue;
    		dfs2(v,v);
    	}
    }
    int LCA(int u,int v)
    {
    	while(top[u]!=top[v])
    	{
    		if(dep[top[u]]<dep[top[v]])swap(u,v);
    		u=fa[top[u]];
    	}
    	return dep[u]<dep[v]?u:v;
    }
    int Dis(int u,int v)
    {
    	return dep[u]+dep[v]-dep[LCA(u,v)]*2;
    }
    /************************************************************************/
    int sum[MAX],size[MAX],Fa[MAX];
    int n,Q,m,val[MAX];
    int Size,root,minr;
    bool vis[MAX];
    void Getroot(int u,int ff)
    {
    	size[u]=1;
    	int ret=0;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;
    		if(v==ff||vis[v])continue;
    		Getroot(v,u);
    		size[u]+=size[v];
    		ret=max(ret,size[v]);
    	}
    	ret=max(ret,Size-size[u]);
    	if(ret<minr)minr=ret,root=u;
    }
    void DFS(int u,int ff)
    {
    	vis[u]=true;Fa[u]=ff;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;
    		if(vis[v])continue;
    		minr=n;Size=size[v];
    		Getroot(v,u);
    		DFS(root,u);
    	}
    }
    struct Node
    {
    	int ls,rs;
    	int lz;
    }t[MAX*150];
    int tot,rt[MAX<<1];
    void Modify(int &now,int l,int r,int L,int R,int w)
    {
    	if(!now)now=++tot;
    	if(l==L&&r==R){t[now].lz+=w;return;}
    	int mid=(l+r)>>1;
    	if(R<=mid)Modify(t[now].ls,l,mid,L,R,w);
    	else if(L>mid)Modify(t[now].rs,mid+1,r,L,R,w);
    	else Modify(t[now].ls,l,mid,L,mid,w),Modify(t[now].rs,mid+1,r,mid+1,R,w);
    }
    int Query(int now,int l,int r,int pos)
    {
    	if(!now)return 0;
    	if(l==r)return t[now].lz;
    	int mid=(l+r)>>1;
    	if(pos<=mid)return Query(t[now].ls,l,mid,pos)+t[now].lz;
    	else return Query(t[now].rs,mid+1,r,pos)+t[now].lz;
    }
    void PModify(int u,int K,int w)
    {
    	Modify(rt[u],0,n,0,K,w);
    	for(int i=u;Fa[i];i=Fa[i])
    	{
    		int dist=Dis(u,Fa[i]);
    		if(K<dist)continue;
    		Modify(rt[Fa[i]],0,n,0,K-dist,w);
    		Modify(rt[i+n],0,n,0,K-dist,w);
    	}
    }
    int PQuery(int u)
    {
    	int ret=Query(rt[u],0,n,0);
    	for(int i=u;Fa[i];i=Fa[i])
    	{
    		int dist=Dis(u,Fa[i]);
    		ret+=Query(rt[Fa[i]],0,n,dist);
    		ret-=Query(rt[i+n],0,n,dist);
    	}
    	return ret;
    }
    int main()
    {
    	n=read();Q=read();
    	for(int i=1;i<n;++i)
    	{
    		int u=read(),v=read();
    		Add(u,v);Add(v,u);
    	}
    	dfs1(1,0);dfs2(1,1);
    	minr=Size=n;Getroot(1,0);
    	DFS(root,0);
    	char ch[2];
    	while(Q--)
    	{
    		scanf("%s",ch);
    		if(ch[0]=='M')
    		{
    			int u=read(),K=read(),w=read();
    			PModify(u,K,w);
    		}
    		else printf("%d
    ",PQuery(read()));
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    Java堆栈详解
    JVM 图形化监控工具
    Tomcat 7优化前及优化后的性能对比
    Java 枚举常见7种用法
    GitHub上如何删除repository仓库
    eclipse下使用git上传(下载)代码至(从)github
    标准的软件工程过程之文档标准
    maven添加本地非repository中的jar包
    Junit初级篇
    mongodb拷贝数据库copyDatabase()。实现释放磁盘空间的方法。
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8279735.html
Copyright © 2011-2022 走看看