• 【bzoj4154】[Ipsc2015]Generating Synergy KD-tree


    题目描述

    给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色

    输入

    第一行一个数T,表示数据组数
    接下来每组数据的第一行三个数n,c,q表示结点个数,颜色数和操作数
    接下来一行n-1个数描述2..n的父节点
    接下来q行每行三个数a,l,c
    若c为0,表示询问a的颜色
    否则将距离a不超过l的a的子节点染成c

    输出

    设当前是第i个操作,y_i为本次询问的答案(若本次操作是一个修改则y_i为0),令z_i=i*y_i,请输出z_1+z_2+...+z_q模10^9+7

    样例输入

    1
    4 3 7
    1 2 2
    3 0 0
    2 1 3
    3 0 0
    1 0 2
    2 0 0
    4 1 1
    4 0 0

    样例输出

    32


    题解

    KD-tree

    “子树内”是dfs序限制,“距离不超过l”是深度限制。对满足两种限制的点的修改,可以将其看作平面上的点,修改相当于矩形修改,使用lazy标记+pushdown即可。

    时间复杂度$O(nsqrt n)$

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 100010
    using namespace std;
    int head[N] , to[N] , next[N] , cnt , deep[N] , pos[N] , last[N] , tot , d , root;
    struct data
    {
    	int p[2] , mx[2] , mn[2] , c[2] , w , tag;
    	bool operator<(const data &a)const {return p[d] == a.p[d] ? p[d ^ 1] < a.p[d ^ 1] : p[d] < a.p[d];}
    }a[N];
    inline void add(int x , int y)
    {
    	to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt;
    }
    void dfs(int x)
    {
    	int i;
    	pos[x] = ++tot , a[x].p[0] = pos[x] , a[x].p[1] = deep[x];
    	for(i = head[x] ; i ; i = next[i])
    		deep[to[i]] = deep[x] + 1 , dfs(to[i]);
    	last[x] = tot;
    }
    inline void pushup(int x)
    {
    	int l = a[x].c[0] , r = a[x].c[1];
    	a[x].mx[0] = max(a[x].p[0] , max(a[l].mx[0] , a[r].mx[0]));
    	a[x].mx[1] = max(a[x].p[1] , max(a[l].mx[1] , a[r].mx[1]));
    	a[x].mn[0] = min(a[x].p[0] , min(a[l].mn[0] , a[r].mn[0]));
    	a[x].mn[1] = min(a[x].p[1] , min(a[l].mn[1] , a[r].mn[1]));
    }
    int build(int l , int r , int now)
    {
    	if(l > r) return 0;
    	int mid = (l + r) >> 1;
    	d = now , nth_element(a + l , a + mid , a + r + 1);
    	a[mid].w = 1 , a[mid].tag = 0;
    	a[mid].c[0] = build(l , mid - 1 , now ^ 1);
    	a[mid].c[1] = build(mid + 1 , r , now ^ 1);
    	pushup(mid);
    	return mid;
    }
    inline void pushdown(int x)
    {
    	if(a[x].tag)
    	{
    		int l = a[x].c[0] , r = a[x].c[1];
    		a[l].w = a[l].tag = a[r].w = a[r].tag = a[x].tag;
    		a[x].tag = 0;
    	}
    }
    void update(int bx , int ex , int by , int ey , int v , int x)
    {
    	if(!x || a[x].mx[0] < bx || a[x].mn[0] > ex || a[x].mx[1] < by || a[x].mn[1] > ey) return;
    	if(a[x].mn[0] >= bx && a[x].mx[0] <= ex && a[x].mn[1] >= by && a[x].mx[1] <= ey)
    	{
    		a[x].w = a[x].tag = v;
    		return;
    	}
    	pushdown(x);
    	if(a[x].p[0] >= bx && a[x].p[0] <= ex && a[x].p[1] >= by && a[x].p[1] <= ey) a[x].w = v;
    	update(bx , ex , by , ey , v , a[x].c[0]) , update(bx , ex , by , ey , v , a[x].c[1]);
    }
    int query(int px , int py , int x)
    {
    	d ^= 1;
    	if(a[x].p[0] == px && a[x].p[1] == py) return a[x].w;
    	pushdown(x);
    	if(d)
    	{
    		if(py < a[x].p[1] || (py == a[x].p[1] && px < a[x].p[0])) return query(px , py , a[x].c[0]);
    		else return query(px , py , a[x].c[1]);
    	}
    	else
    	{
    		if(px < a[x].p[0] || (px == a[x].p[0] && py < a[x].p[1])) return query(px , py , a[x].c[0]);
    		else return query(px , py , a[x].c[1]);
    	}
    }
    int main()
    {
    	int T;
    	scanf("%d" , &T);
    	while(T -- )
    	{
    		memset(head , 0 , sizeof(head)) , cnt = 1;
    		a[0].mx[0] = a[0].mx[1] = -1 << 30 , a[0].mn[0] = a[0].mn[1] = 1 << 30;
    		int n , m , i , x , y , z , ans = 0;
    		scanf("%d%*d%d" , &n , &m);
    		for(i = 2 ; i <= n ; i ++ ) scanf("%d" , &x) , add(x , i);
    		dfs(1);
    		root = build(1 , n , 0);
    		for(i = 1 ; i <= m ; i ++ )
    		{
    			scanf("%d%d%d" , &x , &y , &z);
    			if(z) update(pos[x] , last[x] , deep[x] , deep[x] + y , z , root);
    			else d = 1 , ans = (ans + (long long)query(pos[x] , deep[x] , root) * i) % 1000000007;
    		}
    		printf("%d
    " , ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    python-面向对象-05_面向对象封装案例 II
    python-面向对象-06_私有属性和私有方法
    python-面向对象-07_继承
    python-面向对象-08_多态
    python-面向对象-09_类属性和类方法
    CentOS 7 安装
    lnmp 一键搭建脚本
    shell 函数与内置变量
    linux无敌权限之chattr
    linux运维配置讲解--sshd-config
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7609378.html
Copyright © 2020-2023  润新知