zoukankan      html  css  js  c++  java
  • 树链剖分【p3038】[USACO11DEC]牧草种植Grass Planting

    img

    表示看不太清.

    概括题意

    树上维护区间修改与区间和查询.

    很明显树剖裸题,切掉,细节处错误T了好久 TAT

    代码

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #define int long long
    #define R register
    #define ls o<<1
    #define rs o<<1|1
    #define N 500008
    using namespace std;
    inline void in(int &x)
    {
    	int f=1;x=0;char s=getchar();
    	while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
    	while(isdigit(s)){x=x*10+s-'0';s=getchar();}
    	x*=f;
    }
    int n,m,head[N],tot,f[N],son[N],size[N],depth[N];
    struct cod{int u,v;}edge[N<<2];
    inline void add(int x,int y)
    {
    	edge[++tot].u=head[x];
    	edge[tot].v=y;
    	head[x]=tot;
    }
    void dfs1(int u,int fa)
    {
    	f[u]=fa;depth[u]=depth[fa]+1;size[u]=1;
    	for(R int i=head[u];i;i=edge[i].u)
    	{
    		if(edge[i].v==fa)continue;
    		dfs1(edge[i].v,u);
    		size[u]+=size[edge[i].v];
    		if(son[u]==-1 or size[son[u]]<size[edge[i].v])
    			son[u]=edge[i].v;
    	}
    }
    int idx,dfn[N],fdfn[N],top[N];
    void dfs2(int u,int t)
    {
    	top[u]=t;dfn[u]=++idx;fdfn[idx]=u;
    	if(son[u]==-1)return;
    	dfs2(son[u],t);
    	for(R int i=head[u];i;i=edge[i].u)
    	{
    		if(dfn[edge[i].v])continue;
    		dfs2(edge[i].v,edge[i].v);
    	}
    }
    int tr[N<<2],tg[N<<2],a[N];
    inline void up(int o){tr[o]=tr[ls]+tr[rs];}
    inline void down(int o,int l,int r)
    {
    	if(tg[o])
    	{
    		int mid=(l+r)>>1;
    		tg[ls]+=tg[o];tg[rs]+=tg[o];
    		tr[ls]+=(mid-l+1)*tg[o];
    		tr[rs]+=(r-mid)*tg[o];
    		tg[o]=0;
    	}
    }
    void change(int o,int l,int r,int x,int y,int z)
    {
    	if(x<=l and y>=r)
    	{
    		tr[o]+=(r-l+1)*z;
    		tg[o]+=z;
    		return;
    	}
    	down(o,l,r);
    	int mid=(l+r)>>1;
    	if(x<=mid)change(ls,l,mid,x,y,z);
    	if(y>mid)change(rs,mid+1,r,x,y,z);
    	up(o);
    }
    int query(int o,int l,int r,int x,int y)
    {
    	if(x<=l and y>=r)return tr[o];
    	down(o,l,r);
    	int mid=(l+r)>>1,res=0;
    	if(x<=mid)res+=query(ls,l,mid,x,y);
    	if(y>mid)res+=query(rs,mid+1,r,x,y);
    	return res;
    }
    inline void tchange(int x,int y,int z)
    {
    	int fx=top[x],fy=top[y];
    	while(fx!=fy)
    	{
    		if(depth[fx]>depth[fy])
    		{
    			change(1,1,idx,dfn[fx],dfn[x],z);
    			x=f[fx];
    		}
    		else
    		{
    			change(1,1,idx,dfn[fy],dfn[y],z);
    			y=f[fy];
    		}
    		fx=top[x],fy=top[y];
    	}
    	if(x==y)return;
    	if(dfn[x]>dfn[y])swap(x,y);
    	change(1,1,idx,dfn[x]+1,dfn[y],z);
    }
    inline int tquery(int x,int y)
    {
    	int fx=top[x],fy=top[y],res=0;
    	while(fx!=fy)
    	{
    		if(depth[fx]>depth[fy])
    		{
    			res+=query(1,1,idx,dfn[fx],dfn[x]);
    			x=f[fx];
    		}
    		else
    		{
    			res+=query(1,1,idx,dfn[fy],dfn[y]);
    			y=f[fy];
    		}
    		fx=top[x],fy=top[y];
    	}
    	if(x==y)return res;
    	if(dfn[x]>dfn[y])swap(x,y);
    	res+=query(1,1,idx,dfn[x]+1,dfn[y]);
    	return res;
    }
    char s[10];
    signed main()
    {
    	in(n),in(m);memset(son,-1,sizeof son);
    	for(R int i=1,x,y;i<n;i++)
    	{
    		in(x),in(y);
    		add(x,y),add(y,x);
    	}
    	dfs1(1,0);dfs2(1,1);
    	for(R int x,y;m;m--)
    	{
    		scanf("%s",s);in(x),in(y);
    		if(s[0]=='P')tchange(x,y,1);
    		else printf("%lld
    ",tquery(x,y));
    	}
    }
    
  • 相关阅读:
    Grails笔记二:grails 2.4.3版本下generate-*失效问题解析
    java常量池中基本数据类型包装类的小陷阱
    Mysql中使用聚合函数对null值的处理
    集合框架
    List的三个子类ArrayList,LinkedList,Vector之面试题
    String类面试题2
    String类常见面试题1
    常见对象之String类
    Scanner的概述和方法介绍
    Java开发工具(Eclipse工作空间的基本配置)
  • 原文地址:https://www.cnblogs.com/-guz/p/9806680.html
Copyright © 2011-2022 走看看