codeforces 502 g The Tree
题解:
一道优秀的题目
有几种做法:
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的更多相关文章
- 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 ...
- Codeforces 461B Appleman and Tree(木dp)
题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k ...
- [codeforces 549]G. Happy Line
[codeforces 549]G. Happy Line 试题描述 Do you like summer? Residents of Berland do. They especially love ...
- CodeForces 794 G.Replace All
CodeForces 794 G.Replace All 解题思路 首先如果字符串 \(A, B\) 没有匹配,那么二元组 \((S, T)\) 合法的一个必要条件是存在正整数对 \((x,y)\), ...
- Codeforces 1129 E.Legendary Tree
Codeforces 1129 E.Legendary Tree 解题思路: 这题好厉害,我来复读一下官方题解,顺便补充几句. 首先,可以通过询问 \(n-1\) 次 \((S=\{1\},T=\{ ...
- Codeforces 280C Game on tree【概率DP】
Codeforces 280C Game on tree LINK 题目大意:给你一棵树,1号节点是根,每次等概率选择没有被染黑的一个节点染黑其所有子树中的节点,问染黑所有节点的期望次数 #inclu ...
- Codeforces A. Game on Tree(期望dfs)
题目描述: Game on Tree time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- Codeforces 1207 G. Indie Album
Codeforces 1207 G. Indie Album 解题思路 离线下来用SAM或者AC自动机就是一个单点加子树求和,套个树状数组就好了,因为这个题广义SAM不能存在 \(len[u] = l ...
- Codeforces Round #781(C. Tree Infection)
Codeforces Round #781 C. Tree Infection time limit per test 1 second memory limit per test 256 megab ...
随机推荐
- Djangon
2.怎么样从浏览器获得用户输入的数据? request.浏览器的八种申请方式.get(条件) request.浏览器的八种申请方式[] request.浏览器的八种申请方式(这里什么也不要写)> ...
- 【NLP】Conditional Language Modeling with Attention
Review: Conditional LMs Note that, in the Encoder part, we reverse the input to the ‘RNN’ and it per ...
- Django 序列化
序列化 背景 对于Django 的queryset 对象在传递给 前端的时候,前端是无法识别的 因此需要存在一个转换过程将 queryset 对象转换成 字符串前端才可以识别 演示 QuerySet ...
- XUGUO-书呆子-搜索书箱
WorldCat 上的 米塔斯 通过图书馆馆藏的全球目录WorldCat,在附近的图书馆中查找所要的资料. < 用 Sketch 创作 Airiti Library華藝線上圖書館 BookBub ...
- [ML]机器学习书单
https://anvaka.github.io/greview/hands-on-ml/1/
- [hashcat]基于字典和暴力破解尝试找到rar3-hp的压缩包密码
1.使用rar2john找到md5 2.基于字典 hashcat -a 0 -m 12500 /root/Desktop/md5.txt /usr/share/wordlists/weakpass.t ...
- 为 Java 程序员准备的 Go 入门 PPT
为 Java 程序员准备的 Go 入门 PPT 这是 Google 的 Go 团队技术主管经理 Sameer Ajmani 分享的 PPT,为 Java 程序员快速入门 Go 而准备的. 视频 这个 ...
- Django订单接入支付宝
1.. 去支付宝申请 https://open.alipay.com/platform/home.htm 注:因为创建应用正式接入支付宝需要营业执照,所以我们可以使用沙箱环境来测试. 2. 一次选择管 ...
- Hbase 元数据一致性检查(转)
最近在学习HBase先关的知识,顺便做一下笔记,以加深知识的了解和掌握. Hbase常用工具 文件检测修复工具 hbase hbck -help 常用选项: -details 显示所有region检查 ...
- solr的搜索
主要讲一下solr面板的使用: 查询 q: 查询用 语法: name:刘中华 支持通配符 ? 表示单个任意字符的通配 * 表示多个任意字符的通配(不能在检索的项开始使用*或者?符号 ...