• test20181016 B君的第二题


    题意


    分析

    考场暴力50分。

    考虑bfs序,一个点的儿子节点的bfs序一定连续,所以对bfs序建线段树,努力打一下就行了。

    时间复杂度(O(n log n + m log n))

    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<list>
    #include<deque>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<bitset>
    #include<algorithm>
    #include<complex>
    #define rg register
    #define co const
    #define il inline
    #pragma GCC optimize ("O0")
    using namespace std;
    template<class T> inline T read(T&x)
    {
        T data=0;
    	int w=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
    		if(ch=='-')
    			w=-1;
    		ch=getchar();
    	}
        while(isdigit(ch))
            data=10*data+ch-'0',ch=getchar();
        return x=data*w;
    }
    typedef long long ll;
    const int INF=0x7fffffff;
    
    const int MAXN=2e5+7;
    
    struct Edge
    {
    	int nx,to;
    }E[MAXN<<1];
    int head[MAXN],ecnt;
    
    il void addedge(rg co int&x,rg co int&y)
    {
    	E[++ecnt].to=y;
    	E[ecnt].nx=head[x],head[x]=ecnt;
    }
    
    const int mod=1e9+7;
    
    struct node
    {
    	int sumv;
    	
    	il node(rg co int&s=0):sumv(s){}
    	
    	il node operator+(rg const node&rhs)const
    	{
    		return node((sumv + rhs.sumv) % mod);
    	}
    };
    
    int ql,qr,v;
    struct SegTree
    {
    	node data[MAXN<<2];
    	int addv[MAXN<<2],mulv[MAXN<<2];
    #define lson (now<<1)
    #define rson (now<<1|1)
    	il void build(rg int now,rg int l,rg int r)
    	{
    		addv[now]=0,mulv[now]=1;
    		if(l==r)
    		{
    			data[now].sumv=0;
    			return;
    		}
    		rg int mid=(l+r)>>1;
    		build(lson,l,mid);
    		build(rson,mid+1,r);
    		data[now]=data[lson]+data[rson];
    	}
    	
    	il void pushdown(rg int now,rg int l,rg int r)
    	{
    		if(mulv[now]!=1)
    		{
    			data[lson].sumv = (ll) data[lson].sumv * mulv[now] % mod,
    			addv[lson] = (ll) addv[lson] * mulv[now] % mod;
    			mulv[lson] = (ll) mulv[lson] * mulv[now] % mod;
    			data[rson].sumv = (ll) data[rson].sumv * mulv[now] % mod,
    			addv[rson] = (ll) addv[rson] * mulv[now] % mod;
    			mulv[rson] = (ll) mulv[rson] * mulv[now] % mod;
    			mulv[now] = 1;
    		}
    		if(addv[now])
    		{
    			rg int mid=(l+r)>>1;
    			(data[lson].sumv += (ll) (mid - l + 1) * addv[now] % mod ) %= mod,
    			(addv[lson] += addv[now]) %= mod;
    			(data[rson].sumv += (ll) (r - mid) * addv[now] % mod) %= mod,
    			(addv[rson] += addv[now]) %= mod;
    			addv[now]=0;
    		}
    	}
    	
    	il node query(rg int now,rg int l,rg int r)
    	{
    		if(ql<=l&&r<=qr)
    		{
    			return data[now];
    		}
    		pushdown(now,l,r);
    		rg int mid=(l+r)>>1;
    		if(qr<=mid)
    			return query(lson,l,mid);
    		if(ql>=mid+1)
    			return query(rson,mid+1,r);
    		return query(lson,l,mid)+query(rson,mid+1,r);
    	}
    	
    	il void mul(rg int now,rg int l,rg int r)
    	{
    		if(ql<=l&&r<=qr)
    		{
    			data[now].sumv = (ll)data[now].sumv * v % mod,
    			addv[now] = (ll)addv[now] * v % mod,
    			mulv[now] = (ll)mulv[now] * v % mod;
    			return;
    		}
    		pushdown(now,l,r);
    		rg int mid=(l+r)>>1;
    		if(ql<=mid)
    			mul(lson,l,mid);
    		if(qr>=mid+1)
    			mul(rson,mid+1,r);
    		data[now]=data[lson]+data[rson];
    	}
    	
    	il void add(rg int now,rg int l,rg int r)
    	{
    		if(ql<=l&&r<=qr)
    		{
    			(data[now].sumv += (ll)(r - l + 1) * v % mod) %= mod,
    			(addv[now] += v) %= mod;
    			return;
    		}
    		pushdown(now,l,r);
    		rg int mid=(l+r)>>1;
    		if(ql<=mid)
    			add(lson,l,mid);
    		if(qr>=mid+1)
    			add(rson,mid+1,r);
    		data[now]=data[lson]+data[rson];
    	}
    }T;
    
    int fa[MAXN],s1[MAXN],s2[MAXN];
    
    il void dfs(rg co int&x,rg co int&f)
    {
    	fa[x]=f;
    	for(rg int i=head[x];i;i=E[i].nx)
    	{
    		rg int y=E[i].to;
    		if(y==f)
    			continue;
    		if(!s1[x]) // edit 1:cannot add fa
    			s1[x]=y;
    		s2[x]=y;
    		dfs(y,x);
    	}
    }
    
    int bfn[MAXN],clk;
    
    il void bfs()
    {
    	rg queue<int>Q;
    	Q.push(1);
    	while(!Q.empty())
    	{
    		rg int x=Q.front();
    		Q.pop();
    		bfn[x]=++clk;
    		for(rg int i=head[x];i;i=E[i].nx)
    		{
    			rg int y=E[i].to;
    			if(y==fa[x])
    				continue;
    			Q.push(y);
    		}
    	}
    }
    
    int main()
    {
      freopen("ruby.in","r",stdin);
      freopen("ruby.out","w",stdout);
    	rg int n,m;
    	read(n);read(m);
    	for(rg int i=1;i<n;++i)
    	{
    		rg int x,y;
    		read(x);read(y);
    		addedge(x,y);
    		addedge(y,x);
    	}
    	
    	dfs(1,0);
    	bfs();
    	T.build(1,1,n);
    	
    	while(m--)
    	{
    		rg int x,k,b;
    		read(x);read(k);read(b);
    		
    		rg int ans=0;
    		
    		if(bfn[fa[x]]) // edit 1:fa[root]=NULL
    		{
    			ql=qr=bfn[fa[x]];
    			v=k;
    			T.mul(1,1,n);
    			v=b;
    			T.add(1,1,n);
    			(ans += T.query(1,1,n).sumv) %= mod;
    		}
    		
    		ql=qr=bfn[x];
    		v=k;
    		T.mul(1,1,n);
    		v=b;
    		T.add(1,1,n);
    		(ans += T.query(1,1,n).sumv) %= mod;
    		
    		if(bfn[s1[x]]) // edit 2:leaf has no son
    		{
    			ql=bfn[s1[x]],qr=bfn[s2[x]];
    			v=k;
    			T.mul(1,1,n);
    			v=b;
    			T.add(1,1,n);
    			(ans += T.query(1,1,n).sumv) %= mod;
    		}
    		
    		printf("%d
    ",ans);
    	}
    //  fclose(stdin);
    //  fclose(stdout);
        return 0;
    }
    

    Hint

    第一次打bfs序的题,有些细节需要注意。

    一个点可能没有父节点或没有子节点,需要特判。

    dfs的首尾子节点的赋值注意不要赋值成fa了。

    静渊以有谋,疏通而知事。
  • 相关阅读:
    案例7-1.2 插入排序还是归并排序 (25分)
    自动化运维工具——puppet详解(一)
    centos6.8的安装和配置
    ZooKeeper内部原理
    ZooKeeper安装和配置
    zookeeper入门
    shell中uniq与sort -u 两种去重的对别
    tomcat日志文件 访问IP统计
    Mysql常用命令
    linux一键安装php脚本
  • 原文地址:https://www.cnblogs.com/autoint/p/9806276.html
Copyright © 2020-2023  润新知