题解:

一道优秀的题目

有几种做法:

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. JS-JAVASCRIPT的eval()方法

    Lodop的传统模版是JS语句,如果储存的这种JS模版,可用javascript的eval()方法获取,该方法属于JS的范畴,并不是lodop语句,由于这个方法很多程序员可能不常用,对于这个JS方法不 ...

  2. Nginx 请求的11个阶段

    48 1:当请求进入Nginx后先READ REQUEST HEADERS 读取头部 然后再分配由哪个指令操作 2:Identity 寻找匹配哪个Location  3:Apply Rate Limi ...

  3. magento2 - Invalid credentials for 'https://repo.magento.com/packages.json', aborting.

    错误如下: 登陆:https://developer.magento.com/找到路径-创建公钥与私钥: Developer Portal -> My Access Keys -> Cre ...

  4. MT【315】勾股数

    (高考压轴题)证明以下命题:(1)对任意正整数$a$都存在正整数$b,c(b<c)$,使得$a^2,b^2,c^2$成等差数列.(2)存在无穷多个互不相似的三角形$\Delta_n$,其边长$a ...

  5. django restframework permission

    与 authentication 和 throttling 一起,permission 决定是应该接受还是拒绝访问请求.权限检查总是在视图的最开始处运行,在任何其他代码被允许进行之前.权限检查通常会使 ...

  6. P1313 计算系数

    题目描述 给定一个多项式(by+ax)k(by+ax)^k(by+ax)k,请求出多项式展开后xn×ymx^n \times y^mxn×ym项的系数. 输入输出格式 输入格式: 共一行,包含555个 ...

  7. Python爬虫之二

    1)什么叫做URL url是统一资源定位符,对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址.互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及 ...

  8. URL传递中文参数乱码问题

    web项目开发中,经常遇到中文参数乱码问题,而且有时候明明测试服务器上好用,换个正式环境就不用的情况也经常出现,今天做一个记录,防止自己以后忘记 1.地址栏url请求带中文参数 这类

  9. Redis扩展机制

    Redis扩展机制扫盲 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 关于Redis的Avalibility解决方案有很多,比如Twemproxy,Codis, 一.Twempro ...

  10. Python 文件行数读取的三种方法

    Python三种文件行数读取的方法: #文件比较小 count = len(open(r"d:\lines_test.txt",'rU').readlines()) print c ...