题解:

一道优秀的题目

有几种做法:

1.维护后缀和

刚开始我想的是维护前缀和

然后用$sum[x]-sum[y]>=dep[x]-dep[y]$来做

但是这样子树赋值为0这个操作就很难进行了

因为你查找的是链上最小值,所以不改子树上面的节点是做不了的

那我们换一种方式,单点改,查询区间最大后缀和

这样子树染白的时候我们就可以在x处减去一个上面的最大后缀和,那么就对子树没有影响了

然后再把子树清空一下就可以

其实这个东西就是动态dp。。。

$$f(v)=max(f(x)-1,0)+v[v]$$

这个只用查询链

所以我们只需要维护$f[v]=MAX(f[top]必选时的最大值k1,任意情况最大值k2)$就可以了(v都是必选点)

#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for(int i=h;i<=t;i++)
#define dep(i,t,h) for(int i=t;i>=h;i--)
#define ll long long
#define me(x) memset(x,0,sizeof(x))
#define mep(x,y) memcpy(x,y,sizeof(y))
#define mid ((h+t)>>1)
namespace IO{
char ss[<<],*A=ss,*B=ss;
IL char gc()
{
return A==B&&(B=(A=ss)+fread(ss,,<<,stdin),A==B)?EOF:*A++;
}
template<class T> void read(T &x)
{
rint f=,c; while (c=gc(),c<||c>) if (c=='-') f=-; x=(c^);
while (c=gc(),c>&&c<) x=(x<<)+(x<<)+(c^); x*=f;
}
char sr[<<],z[]; ll Z,C1=-;
template<class T>void wer(T x)
{
if (x<) sr[++C1]='-',x=-x;
while (z[++Z]=x%+,x/=);
while (sr[++C1]=z[Z],--Z);
}
IL void wer1()
{
sr[++C1]=' ';
}
IL void wer2()
{
sr[++C1]='\n';
}
template<class T>IL void maxa(T &x,T y) {if (x<y) x=y;}
template<class T>IL void mina(T &x,T y) {if (x>y) x=y;}
template<class T>IL T MAX(T x,T y){return x>y?x:y;}
template<class T>IL T MIN(T x,T y){return x<y?x:y;}
};
using namespace IO;
const int N=2.1e5;
struct re{
int a,b;
}e[N*];
int head[N],l,n,m;
IL void arr(int x,int y)
{
e[++l].a=head[x];
e[l].b=y;
head[x]=l;
}
struct re2{
int a[];
re2() { a[]=a[]=; }
re2(int x,int y) {a[]=x; a[]=y;};
re2 operator *(const re2 &o) const
{
re2 c;
c.a[]=a[]+o.a[]; c.a[]=MAX(a[]+o.a[],o.a[]);
return c;
}
};
int fa[N],num[N],son[N],dfn[N],top[N],cnt;
void dfs(int x,int y)
{
num[x]=; fa[x]=y;
for (rint u=head[x];u;u=e[u].a)
{
int v=e[u].b;
if (v!=y)
{
dfs(v,x);
num[x]+=num[v];
if (num[son[x]]<num[v]) son[x]=v;
}
}
}
void dfs1(int x,int y,int z)
{
top[x]=y; dfn[x]=++cnt;
if (son[x]) dfs1(son[x],y,x);
for (rint u=head[x];u;u=e[u].a)
{
int v=e[u].b;
if (v!=z&&v!=son[x])
{
dfs1(v,v,x);
}
}
}
struct sgt{
re2 sum[N*];
bool lazy[N*];
#define updata(x) sum[x]=sum[x*2]*sum[x*2+1]
IL void down(int x,int h,int t)
{
if (lazy[x])
{
lazy[x*]=lazy[x*+]=; lazy[x]=;
sum[x*]=re2(-(mid-h+),-);
sum[x*+]=re2(-(t-mid),-);
}
}
void build(int x,int h,int t)
{
if (h==t) { sum[x]=re2(-,-); return;}
build(x*,h,mid); build(x*+,mid+,t);
updata(x);
}
void change(int x,int h,int t,int pos,int k)
{
if (h==t) { sum[x]=re2(k,k);return; }
down(x,h,t);
if (pos<=mid) change(x*,h,mid,pos,k);
else change(x*+,mid+,t,pos,k);
updata(x);
}
re2 query(int x,int h,int t,int h1,int t1)
{
if (h1<=h&&t<=t1) return sum[x];
down(x,h,t);
if (h1<=mid&&mid<t1) return query(x*,h,mid,h1,t1)*query(x*+,mid+,t,h1,t1);
else if (h1<=mid) return query(x*,h,mid,h1,t1);
else return query(x*+,mid+,t,h1,t1);
}
void push(int x,int h,int t,int h1,int t1)
{
if (h1<=h&&t<=t1) { lazy[x]=; sum[x]=re2(-(t-h+),-); return;}
down(x,h,t);
if (h1<=mid) push(x*,h,mid,h1,t1);
if (mid<t1) push(x*+,mid+,t,h1,t1);
updata(x);
}
}S;
IL int query(int x)
{
int ans=-;
re2 p1=re2(,-);
while (x)
{
re2 p=S.query(,,n,dfn[top[x]],dfn[x]);
p1=p*p1;
ans=max(ans,p1.a[]);
x=fa[top[x]];
}
return ans;
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
read(n); read(m);
rep(i,,n)
{
int x;
read(x);
arr(i,x); arr(x,i);
}
dfs(,); dfs1(,,);
S.build(,,n);
rep(i,,m)
{
int kk,x;
read(kk); read(x);
if (kk==)
{
S.change(,,n,dfn[x],S.query(,,n,dfn[x],dfn[x]).a[]+);
}
if (kk==)
{
S.push(,,n,dfn[x],dfn[x]+num[x]-);
int ans=query(x);
S.change(,,n,dfn[x],-ans-);
}
if (kk==)
{
if (query(x)>=) cout<<"black"<<endl;
else cout<<"white"<<endl;
}
}
return ;
}

2.操作分块

分块这个东西有的时候的确简单巧妙。。

但一般我也不会去想分块。。

这个是看了别人题解的。。

我们以每$\sqrt{n}$个元素分一组

对块内的操作,我们等待$\sqrt{n}$都做完了再把这$\sqrt{n}$个操作加入树中

对于当前的询问,我们只需要树内的$\sqrt{n}$个节点的信息就可以了

我们可以建立虚树维护

本来打算学树上分块的。。。但发现这东西并没有啥用

会线段树合并/dsu on tree/树上莫队 应该不会也没啥关系

像这种利用虚树的题目还是比较多的

codeforces 502 g The Tree的更多相关文章

  1. Codeforces Round #502 (in memory of Leopoldo Taravilse, Div. 1 + Div. 2) G. The Tree

    G. The Tree time limit per test 3 seconds memory limit per test 256 megabytes input standard input o ...

  2. Codeforces 461B Appleman and Tree(木dp)

    题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k ...

  3. [codeforces 549]G. Happy Line

    [codeforces 549]G. Happy Line 试题描述 Do you like summer? Residents of Berland do. They especially love ...

  4. CodeForces 794 G.Replace All

    CodeForces 794 G.Replace All 解题思路 首先如果字符串 \(A, B\) 没有匹配,那么二元组 \((S, T)\) 合法的一个必要条件是存在正整数对 \((x,y)\), ...

  5. Codeforces 1129 E.Legendary Tree

    Codeforces 1129 E.Legendary Tree 解题思路: 这题好厉害,我来复读一下官方题解,顺便补充几句. 首先,可以通过询问 \(n-1​\) 次 \((S=\{1\},T=\{ ...

  6. Codeforces 280C Game on tree【概率DP】

    Codeforces 280C Game on tree LINK 题目大意:给你一棵树,1号节点是根,每次等概率选择没有被染黑的一个节点染黑其所有子树中的节点,问染黑所有节点的期望次数 #inclu ...

  7. Codeforces A. Game on Tree(期望dfs)

    题目描述: Game on Tree time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  8. Codeforces 1207 G. Indie Album

    Codeforces 1207 G. Indie Album 解题思路 离线下来用SAM或者AC自动机就是一个单点加子树求和,套个树状数组就好了,因为这个题广义SAM不能存在 \(len[u] = l ...

  9. Codeforces Round #781(C. Tree Infection)

    Codeforces Round #781 C. Tree Infection time limit per test 1 second memory limit per test 256 megab ...

随机推荐

  1. linux 实现centos7在线升级最新版本内核

    Kernel  (内核)是操作系统的核心,掌握所有硬件设备的控制权,也就是说,你所希望计算机帮你完成的各项工作,都需要通过内核的帮助才能完成,当然,如果我们想完成的某个功能是内核没有的,则内核不会操控 ...

  2. jsp篇 之 指令元素和动作元素

    Jsp指令元素分类与书写格式: 书写格式: <%@ 指令类型  属性="值" ..  %> 分类: [page include taglib]三种. 1,page指令: ...

  3. Nginx安全相关配置和nginx.conf中文详解

    一.centos下redis安全相关 1.背景 在使用云服务器时,如果我们的redis关闭了protected-mode模式,被病毒攻击的可能会大大增加,因此我们使用redis时候,最好更改默认端口, ...

  4. BBS 502 BadGateway 原因分析

    说明: LNMP架构. crontab里有每隔20分钟重启php的任务:然后我用python写了个每1分钟检测php-cgi进程是否存在的脚本,如果不存在则调用重启php的脚本,并邮件通知管理员.cr ...

  5. rest framework 认证 权限 频率

    认证组件 发生位置 APIview 类种的 dispatch 方法执行到 initial 方法 进行 认证组件认证 源码位置 rest_framework.authentication  源码内部需要 ...

  6. 学习Spring Boot:(十五)使用Lombok来优雅的编码

    前言 Lombok 是一种 Java™ 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO).它通过注解实现这一目的. 正文 添加依赖 在 pom.xml ...

  7. Java中String连接性能的分析【转】

    [转]http://www.blogjava.net/javagrass/archive/2010/01/24/310650.html 总结:如果String的数量小于4(不含4),使用String. ...

  8. CMDB服务器管理系统【s5day89】:部分数据表结构-资产入库思路

    1.用django的app作为统一调用库的好处 1.创建repository app截图如下: 2.好处如下: 1.app的本质就是一个文件夹 2.以后所有的app调用数据就只去repository调 ...

  9. 金融量化分析【day110】:IPython介绍及简单操作

    一. IPython介绍 ipython是一个python的交互式shell,比默认的python shell好用得多,支持变量自动补全,自动缩进,支持bash shell命令,内置了许多很有用的功能 ...

  10. Flask Web中文教程

    Flask Web中文教程:http://docs.jinkan.org/docs/flask/