题解:

一道优秀的题目

有几种做法:

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. UOJ#348 州区划分

    解:有一个很显然的状压...... 就设f[s]表示选的点集为s的时候所有方案的权值和. 于是有f[s] = f[s \ t] * (sum[t] / sum[s])P. 这枚举子集是3n的. 然后发 ...

  2. 从浅入深详解独立ip网站域名恶意解析的解决方案

    立IP空间的好处想必大家都能耳熟闻详,稳定性强,利于seo等让大家选择了鼎峰网络香港独立IP空间.那么, 网站独享服务器IP地址,独立IP空间利于百度收录和权重的积累.不受牵连.稳定性强等诸多优势为一 ...

  3. TOMCAT ---> servlet概念

    1 TOMCAT ---> servlet概念 2 TOMCAT 目录结构 (各个文件夹都存放什么东西) 3 TOMCAT 程序的层级 web | |---- js,jsp,html,css ( ...

  4. 20175209 《Java程序设计》第二周学习总结

    教材学习内容总结 二三章介绍的主要是Java中的基本知识:数据类型及转换,数据的输入输出,数组,运算符表达式,和常见的一些语句,这些都是帮助我们学习Java的基本知识,而这些知识很大一部分都和C语言相 ...

  5. CMDB服务器管理系统【s5day88】:采集资产之Agent、SSH和Salt模式讲解

    在对获取资产信息时,简述有四种方案. 1.Agent  (基于shell命令实现) 原理图 Agent方式,可以将服务器上面的Agent程序作定时任务,定时将资产信息提交到指定API录入数据库 优点: ...

  6. 第九节: 利用RemoteScheduler实现Sheduler的远程控制

    一. RemoteScheduler远程控制 1. 背景: 在A服务器上部署了一个Scheduler,我们想在B服务器上控制这个Scheduler. 2. 猜想: A服务器上的Scheduler需要有 ...

  7. C# GetHashCode在x64与x86版本下不一样

    最好指定一下目标平台

  8. updateXML 注入 python 脚本

    用SLQMAP来跑updateXML注入发现拦截关键字,然后内联注入能绕,最后修改halfversionedmorekeywords.py脚本,结果SQLMAP还是跑不出来.>_< hal ...

  9. 083_Remove Duplicates from Sorted List

    class ListNode: def __init__(self,x): self.val=x self.next=None ####注意这道题并不是把重复元素全部去掉而是保留一个#### #### ...

  10. django发送邮件send_mail&send_mass_mail

    一.配置 在setting.py中进行相关配置: EMAIL_HOST = 'smtp.sina.cn' #SMTP地址 EMAIL_PORT = 25 #SMTP端口 EMAIL_HOST_USER ...