考完了可以发题解了。

做法是link-cut tree维护子树信息,并不需要维护黑树白树那些的。

下面是一条重链:

如果4是根的话,那么在splay上是这样的:

在splay中,子树的信息都已经计算完毕,那么需要计算这个子树的答案。

这个子树有4个部分:

4:树根。

1,2,3:树根上面的点。

5,6:树根下面的点。

other:树根的虚子树。

那么简化一下:

显然是需要记录答案的,还要记录什么?

  • 3,4会受到1,2的影响,所以答案要加上3,4中黑点数×1,2中权值和
  • 1会受到2的影响,所以答案要加上1中黑点数×2中权值和
  • 没了。剩下的都在原来就计算好了。

所以还要记子树黑点数和权值和。

然后就做完了。

注意一下,splay有reverse操作,所以还要记一个反的答案(丧心病狂,,,),不过虚子树答案不用反过来。

// It is made by XZZ
#include<cstdio>
#include<algorithm>
#define il inline
#define rg register
#define vd void
#define sta static
typedef long long ll;
il int gi(){
rg int x=0,f=1;rg char ch=getchar();
while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int maxn=4e5+1;
int ch[maxn][2],fa[maxn],w[maxn];
ll lans[maxn],rans[maxn],_ans[maxn],tot[maxn],_tot[maxn],W[maxn];
bool col[maxn];
bool rev[maxn];
typedef const int& ci;
il vd Rev(ci x){if(x)rev[x]^=1,std::swap(ch[x][0],ch[x][1]),std::swap(lans[x],rans[x]);}
il bool isrt(ci x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
il vd down(ci x){
if(!x)return;
if(!isrt(x))down(fa[x]);
if(rev[x])Rev(ch[x][0]),Rev(ch[x][1]),rev[x]=0;
}
il vd upd(ci x){
if(!x)return;
W[x]=W[ch[x][0]]+W[ch[x][1]]+w[x];
tot[x]=_tot[x]+tot[ch[x][0]]+tot[ch[x][1]]+col[x];
lans[x]=_ans[x]+lans[ch[x][0]]+lans[ch[x][1]]+(_tot[x]+tot[ch[x][1]]+col[x])*(w[x]+W[ch[x][0]]);
rans[x]=_ans[x]+rans[ch[x][1]]+rans[ch[x][0]]+(_tot[x]+tot[ch[x][0]]+col[x])*(w[x]+W[ch[x][1]]);
}
il vd rotate(ci x){
rg int y=fa[x],z=fa[fa[x]],o=x==ch[y][1];
if(!isrt(y))ch[z][y==ch[z][1]]=x;fa[x]=z;
ch[y][o]=ch[x][!o];fa[ch[x][!o]]=y;
fa[y]=x;ch[x][!o]=y;
upd(y);
}
il vd splay(ci x){
down(x);
rg int y,z;
for(y=fa[x],z=fa[y];!isrt(x);rotate(x),y=fa[x],z=fa[y])
if(!isrt(y))rotate(((x==ch[y][1])==(y==ch[z][1]))?y:x);
upd(x);
}
il vd access(int x){
for(rg int y=0;x;x=fa[y=x]){
splay(x);
_tot[x]+=tot[ch[x][1]]-tot[y];
_ans[x]+=lans[ch[x][1]]-lans[y];
ch[x][1]=y;
upd(x);
}
}
il vd makert(ci x){access(x),splay(x);Rev(x);}
il vd link(ci x,ci y){
makert(x),makert(y);
_tot[x]+=tot[y];
_ans[x]+=lans[y];
fa[y]=x;upd(x);
}
il vd cut(ci x,ci y){
makert(x),access(y),splay(y);
int z=ch[y][0];
ch[z][0]=fa[y]=ch[x][0]=fa[z]=0;
upd(y);
}
int main(){
int n=gi(),m=gi(),k=gi(),cnt=n,u,v,_w;
while(m--){
u=gi(),v=gi(),_w=gi();
++cnt;w[cnt]=W[cnt]=_w;link(u,cnt),link(v,cnt);
}
char opt[2];
while(k--){
scanf("%s",opt);
if(opt[0]=='L'){
u=gi(),v=gi(),_w=gi();
w[++cnt]=_w;link(u,cnt),link(v,cnt);
}else if(opt[0]=='C'){
u=gi(),v=gi();
makert(u),access(v),splay(v);
int z=ch[v][0];
if(ch[z][1])z=ch[z][1];
cut(u,z),cut(v,z);
}
else if(opt[0]=='F')u=gi(),makert(u),col[u]^=1,upd(u);
else if(opt[0]=='Q')u=gi(),makert(u),printf("%lld\n",lans[u]);
}
return 0;
}

2.4KB

loj558 「Antileaf's Round」我们的CPU遭到攻击的更多相关文章

  1. LOJ #556. 「Antileaf's Round」咱们去烧菜吧

    好久没更博了 咕咕咕 现在多项式板子的常数巨大...周末好好卡波常吧.... LOJ #556 题意 给定$ m$种物品的出现次数$ B_i$以及大小$ A_i$ 求装满大小为$[1..n]$的背包的 ...

  2. 【刷题】LOJ 556 「Antileaf's Round」咱们去烧菜吧

    题目描述 你有 \(m\) 种物品,第 \(i\) 种物品的大小为 \(a_i\) ​,数量为 \(b_i\)​( \(b_i=0\) 表示有无限个). 你还有 \(n\) 个背包,体积分别为 \(1 ...

  3. LOJ#557. 「Antileaf's Round」你这衣服租来的吗(FHQ Treap+珂朵莉树)

    题面 传送门 题解 好吧我是不太会复杂度分析-- 我们对于每种颜色用一个数据结构维护(比方说线段树或者平衡树,代码里写的平衡树),那么区间询问很容易就可以解决了 所以现在的问题是区间修改,如果区间颜色 ...

  4. 「LOJ 556 Antileaf's Round」咱们去烧菜吧

    「LOJ 556 Antileaf's Round」咱们去烧菜吧 最近在看 jcvb 的生成函数课件,顺便切一切上面讲到的内容的板子题,这个题和课件上举例的背包计数基本一样. 解题思路 首先列出答案的 ...

  5. 「LibreOJ NOI Round #2」不等关系

    「LibreOJ NOI Round #2」不等关系 解题思路 令 \(F(k)\) 为恰好有 \(k\) 个大于号不满足的答案,\(G(k)\) 表示钦点了 \(k\) 个大于号不满足,剩下随便填的 ...

  6. LibreOJ #507. 「LibreOJ NOI Round #1」接竹竿

    二次联通门 : LibreOJ #507. 「LibreOJ NOI Round #1」接竹竿 /* LibreOJ #507. 「LibreOJ NOI Round #1」接竹竿 dp 记录一下前驱 ...

  7. 对于前端,「微信小程序」其实不美好

    微信小程序开放公测了,9月底我曾经写过一篇 「微信小程序」来了,其中最后一句:"谢天谢地,我居然还是个前端". 这种火爆的新事物总是令人激动,感谢这个时代. 但是,当我真作为开发者 ...

  8. macOS安装「oh my zsh」

    目前常用的 Linux 系统和 OS X 系统的默认 Shell 都是 bash,但是真正强大的 Shell 是深藏不露的 zsh, 这货绝对是马车中的跑车,跑车中的飞行车,史称『终极 Shell』, ...

  9. 报名|「OneAPM x DaoCloud」技术公开课:Docker性能监控!

    如今,越来越多的公司开始 Docker 了,「三分之二的公司在尝试了 Docker 后最终使用了它」,也就是说 Docker 的转化率达到了 67%,同时转化时长也控制在 60 天内. 既然 Dock ...

随机推荐

  1. Oracle恢复删除数据

    可以通过SCN和时间戳两种方法来恢复. 一.通过SCN恢复删除且已经提交的数据 查询当前SCN select current_scn from v$database; 如图: 缩小范围进行查询 查询到 ...

  2. Linux 系统的用户和组详解_【all】

    1.Linux 用户和用户组详解 2.Linux 文件特殊权限详解 3.Linux 文件的读写执行权限的说明 4.Linux 架构之简述企业网站 5.Linux 环境变量设置详解 6.企业生产环境用户 ...

  3. Python运算符之三元运算符

    三元运算符:也称之为条件表达式 [条件为真的结果] if 条件 else [条件为假的结果] 如: ium01 = 100 if100 > 200 else200 print(num01) #三 ...

  4. 成为技术领导者笔记--领导的MOI模型

    一. 想让周围环境发生变化,环境必须包含三个条件: M:激励(Motivation)---有奖品或有困难,这样才对相关人员有推动力或吸引力. O:组织(organization)---利用现有的组织结 ...

  5. fun() 的 拆分和 for 遍历 的结合---------> 函数容器

    fun() 的 拆分和 for 遍历 的结合--------->  函数容器

  6. php分享一个n维数组转一维的函数

    好玩,所以做了这么一个函数,来输出唐诗 函数如下 function changearr($arr){ if(count($arr)==count($arr,1)){ return $arr; } el ...

  7. JVM 调优参数详解

    GC有两种类型:Scavenge GC 和Full GC 1.Scavenge GC 一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC,堆的Eden区域进行GC, ...

  8. 浅析JS中的堆内存与栈内存

    最近跟着组里的大佬面试碰到这么一个问题, Q:说说var.let.const的区别 A:balabalabalabla... Q:const定义的值能改么? A:你逗我?不能吧 不知道各位看官怎么想? ...

  9. using指令都用了这么多年了,其实还真没懂!

    在C语言中,我们经常使用#include<stdio.h>指令来导入标准输入输出库,这确实很好理解,相当于把代码复制到当前的程序中. 但在C#语言中,当我们写Console程序时,经常在第 ...

  10. active developer path ("/Applications/Xcode.app/Contents/Developer")

    -> git xcrun: error: active developer path ("/Applications/Xcode.app/Contents/Developer" ...