3.28 省选模拟赛 染色 LCT+线段树
发现和SDOI2017树点涂色差不多 但是当时这道题模拟赛的时候不会写 赛后也没及时订正 所以这场模拟赛的这道题虽然秒想到了LCT和线段树但是最终还是只是打了暴力。
痛定思痛 还是要把这道题给补了。
但是对于这道题来说 暴力还是有价值的。
考虑20分 每次暴力dfs.
考虑对于树是随机生成的 那么期望高度为logn 我们发现每次修改只用修改到1 也就是说每次暴力修改颜色的话只需要logn的时间复杂度.
考虑如何动态维护子树内的值 考虑修改一个点的颜色 子树内之前和它颜色一样的点 显然子树内部整体答案+1 如果不一样那么没有影响 和当前一样也没有影响。
考虑这个点和它的父亲此时答案是一样的如果原来答案也是一样的 那么没有任何的修改 如果不一样 那么子树内部整体-1.
依靠这个思路我们可以 维护一棵线段树 logn的时间内进行区间修改 区间查询。
考虑100分的做法 发现我们暴力慢的地方在于每次都要向上跳。
有优化的地方是 如果当前点可能树上的一段区间颜色是一样的 我们只需要在 当前修改节点x和那段颜色一样的点y的LCA处修改 剩下的直接向上跳即可。
换个角度 其实这个染颜色其实像是LCT 的ACCESS操作 这样我们就可以很方便的维护上述的操作。
考虑这样做的向上跳的复杂度 可以发现利用LCT的性质 均摊logn.
所以每次在access的时候 完成子树内部的修改即可。维护dfs序线段树 复杂度nlog^2.
const int MAXN=150010;
int n,Q,len,cnt;
int lin[MAXN],c[MAXN][2],f[MAXN],ver[MAXN<<1],nex[MAXN<<1],dfn[MAXN],out[MAXN];
int fa[MAXN],d[MAXN],sz[MAXN],son[MAXN],top[MAXN],v[MAXN];
inline void add(int x,int y)
{
ver[++len]=y;
nex[len]=lin[x];
lin[x]=len;
}
inline void dfs(int x)
{
sz[x]=1;
go(x)if(tn^fa[x])
{
fa[tn]=x;d[tn]=d[x]+1;
dfs(tn);
sz[x]+=sz[tn];
if(sz[tn]>sz[son[x]])son[x]=tn;
}
}
inline void dfs(int x,int father)
{
top[x]=father;dfn[x]=++cnt;v[cnt]=x;
if(son[x])dfs(son[x],father);
go(x)if(tn!=fa[x]&&tn!=son[x])dfs(tn,tn);
out[x]=cnt;
}
inline int LCA(int x,int y)
{
while(top[x]^top[y])
{
if(d[top[x]]<d[top[y]])swap(x,y);
x=fa[top[x]];
}
return d[x]<d[y]?x:y;
}
struct seg{int tag,mx,l,r;ll sum;}t[MAXN<<2];
inline void spread(int p,int v)
{
tag(p)+=v;mx(p)+=v;
sum(p)+=(r(p)-l(p)+1)*v;
}
inline void pushdown(int p)
{
spread(zz,tag(p));
spread(yy,tag(p));
tag(p)=0;
}
inline void pushup(int p)
{
mx(p)=max(mx(zz),mx(yy));
sum(p)=sum(zz)+sum(yy);
}
inline void build(int p,int l,int r)
{
l(p)=l;r(p)=r;
if(l==r){mx(p)=d[v[l]];sum(p)=d[v[l]];return;}
int mid=(l+r)>>1;
build(zz,l,mid);build(yy,mid+1,r);
pushup(p);
}
inline void change(int p,int l,int r,int x)
{
if(l<=l(p)&&r>=r(p)){spread(p,x);return;}
int mid=(l(p)+r(p))>>1;
if(tag(p))pushdown(p);
if(l<=mid)change(zz,l,r,x);
if(r>mid)change(yy,l,r,x);
pushup(p);
}
inline int ask(int p,int x)
{
if(l(p)==r(p))return mx(p);
int mid=(l(p)+r(p))>>1;
if(tag(p))pushdown(p);
if(x<=mid)return ask(zz,x);
return ask(yy,x);
}
inline int ask(int p,int l,int r)
{
if(l<=l(p)&&r>=r(p))return mx(p);
int mid=(l(p)+r(p))>>1,w=0;
if(tag(p))pushdown(p);
if(l<=mid)w=ask(zz,l,r);
if(r>mid)w=max(w,ask(yy,l,r));
return w;
}
inline ll asksum(int p,int l,int r)
{
if(l<=l(p)&&r>=r(p))return sum(p);
int mid=(l(p)+r(p))>>1;ll w=0;
if(tag(p))pushdown(p);
if(l<=mid)w=asksum(zz,l,r);
if(r>mid)w=w+asksum(yy,l,r);
return w;
}
inline void asksum(int x)
{
ll w=asksum(1,dfn[x],out[x]);
double ans=1.0*w/sz[x];
printf("%.10lf\n",ans);
}
inline int pd(int x){return c[f[x]][1]==x||c[f[x]][0]==x;}//判断x是否为根.
inline void rotate(int x)
{
int old=f[x],oldf=f[old],k=c[old][1]==x;
c[old][k]=c[x][k^1];c[x][k^1]=old;
if(pd(old))c[oldf][c[oldf][1]==old]=x;
if(c[old][k])f[c[old][k]]=old;
f[old]=x;f[x]=oldf;
}
inline void splay(int x)
{
while(pd(x))
{
if(pd(f[x]))rotate((c[f[x]][1]==x)^(c[f[f[x]]][1]==f[x])?x:f[x]);
rotate(x);
}
}
inline int findroot(int x)
{
splay(x);
while(c[x][0])x=c[x][0];
splay(x);return x;
}
inline void access(int x)
{
int y=0;
while(x)
{
splay(x);
if(c[x][1])
{
int w=c[x][1];
c[x][1]=0;
w=findroot(w);
change(1,dfn[w],out[w],1);
}
if(y)
{
y=findroot(y);
change(1,dfn[y],out[y],-1);
}
c[x][1]=y;
y=x;x=f[x];
}
}
int main()
{
freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
get(n);
rep(2,n,i)
{
int x,y;
get(x)+1;get(y)+1;
//cout<<x<<' '<<y<<endl;
add(x,y);add(y,x);
}
get(Q);dfs(1);dfs(1,1);
build(1,1,n);
rep(1,n,i)f[i]=fa[i];
rep(1,Q,i)
{
char ch=getc();
while(ch!='q'&&ch!='O')ch=getc();
int get(x)+1;
if(ch=='O')access(x);
else asksum(x);
}
return 0;
}
3.28 省选模拟赛 染色 LCT+线段树的更多相关文章
- 4.11 省选模拟赛 序列 二分 线段树优化dp set优化dp 缩点
容易想到二分. 看到第一个条件容易想到缩点. 第二个条件自然是分段 然后让总和最小 容易想到dp. 缩点为先:我是采用了取了一个前缀最小值数组 二分+并查集缩点 当然也是可以直接采用 其他的奇奇怪怪的 ...
- 6.18 省选模拟赛 字符串 LCT SAM
LINK:字符串 看起来很难做 考虑一种暴力 建立SAM后每次查询暴力扫儿子. 期望得分10分.实际得分10分. 另外一种发现每次扫儿子过于暴力 可以每次儿子向上做贡献 每次都暴力向上跳. 期望得分1 ...
- 6.3 省选模拟赛 Decompose 动态dp 树链剖分 set
LINK:Decompose 看起来很难 实际上也很难 考验选手的dp 树链剖分 矩阵乘法的能力. 容易列出dp方程 暴力dp 期望得分28. 对于链的情况 容易发现dp方程可以转矩阵乘法 然后利用线 ...
- 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护
线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...
- 【Foreign】染色 [LCT][线段树]
染色 Time Limit: 20 Sec Memory Limit: 256 MB Description Input Output Sample Input 13 0 1 0 2 1 11 1 ...
- 4.17 省选模拟赛 远行 LCT 启发式合并 倍增
容易写出nQ的暴力 由于数据是期望的时间 所以直接dfs可以跑的很快 可以拿到70分. 当然 可以进一步优化暴力 使用换根dp 然后可以将暴力优化到n^2. const int MAXN=300010 ...
- 4.28 省选模拟赛 负环 倍增 矩阵乘法 dp
容易想到 这个环一定是简单环. 考虑如果是复杂环 那么显然对于其中的第一个简单环来说 要么其权值为负 如果为正没必要走一圈 走一部分即可. 对于前者 显然可以找到更小的 对于第二部分是递归定义的. 综 ...
- 4.28 省选模拟赛模拟赛 最佳农场 二维卷积 NTT
第一次遇到二维卷积 不太清楚是怎么做的. 40分暴力比对即可. 对于行为或者列为1时 容易想到NTT做快速匹配.然后找答案即可. 考虑这是一个二维的比对过程. 设\(f_{i,j}\)表示以i,j为右 ...
- 4.12 省选模拟赛 LCA on tree 树链剖分 树状数组 分析答案变化量
LINK:duoxiao OJ LCA on Tree 题目: 一道树链剖分+树状数组的神题. (直接nQ的暴力有50. 其实对于树随机的时候不难想到一个算法 对于x的修改 暴力修改到根. 对于儿子的 ...
随机推荐
- POJ 3977 题解
题目 Given a list of N integers with absolute values no larger than \(10^{15}\), find a non empty subs ...
- 安装nodejs,npm,yarn
先安装nodejs和npm sudo apt update sudo apt install nodejs npm #验证一下 nodejs --version npm --version 如果nod ...
- DVWA学习记录 PartⅡ
Command Injection 1. 题目 Command Injection,即命令注入,是指通过提交恶意构造的参数破坏命令语句结构,从而达到执行恶意命令的目的. 2. Low a. 代码分析 ...
- Spring Bean前置后置处理器的使用
Spirng中BeanPostProcessor和InstantiationAwareBeanPostProcessorAdapter两个接口都可以实现对bean前置后置处理的效果,那这次先讲解一下B ...
- 解决使用resin服务器Unsupported major.minor version 51.0错误
是因为jdk版本不对,更换成需要的版本
- Arctic Code Vault Contributor 上榜了 go-admin v1.1 beta 版本发布
Arctic Code Vault Contributor 上榜了,内心比较喜悦,谢谢开源社区的支持,也谢谢广大 coder 的支持: go-admin 是一个基于 Gin + Vue + Eleme ...
- js中实现继承的方法
目录 借用构造函数 组合继承 原型式继承 寄生式继承 寄生组合式继承 借用构造函数 这种技术的基本思想很简单,就是在子类型构造函数的内部调用超类型的构造函数.另外,函数只不过是在特定环境中执行代码的对 ...
- 【JVM之内存与垃圾回收篇】类加载子系统
类加载子系统 概述 完整图如下: 如果自己想手写一个 Java 虚拟机的话,主要考虑哪些结构呢? 类加载器 执行引擎 类加载器子系统作用 类加载器子系统负责从文件系统或者网络中加载 Class 文件, ...
- 一起学Blazor WebAssembly 开发(2)
上篇文章讲了Blazor的两种模式的区别及各自的使用场景,本篇就开始学习WebAssembly模式,本篇主要学习的是创建项目及认识项目结构: 创建项目 选择Blazor应用 选择WebAssembly ...
- Python网络爬虫四大选择器用法原理总结
前几天小编连续写了四篇关于Python选择器的文章,分别用正则表达式.BeautifulSoup.Xpath.CSS选择器分别抓取京东网的商品信息.今天小编来给大家总结一下这四个选择器,让大家更加深刻 ...