Short But Scary

正解的离线分治+虚树的做法太神奇...搞不到

搞一个菜一点的ddp写写,结果调了200年,下次一定写树剖不写lct了,太难调了...

大概就是按sub2那样维护

你每个重链开一个线段树,然后链头把贡献扔给别的重链,然后每次在链上二分位置查一个和差不多了

然后可以拿lct写

但你得搞清楚翻转的时候要翻转的东西比较多,细节也比较多,异常的难写...

算了懒得说了,给我毒瘤死了...


Code:

#include <cstdio>
#include <cctype>
#include <algorithm>
#define ls ch[now][0]
#define rs ch[now][1]
#define fa par[now]
const int N=1e5+10;
template <class T>
void read(T &x)
{
x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
int head[N],to[N<<1],Next[N<<1],cnt;
void add(int u,int v)
{
to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
}
int n,m;
int ch[N][2],par[N],tag[N];//翻转标记
struct koito_yuu
{
int siz,is,lef,dat,si;
//实际大小,子树全是,最左边的点是否是,与父亲关系,虚儿子贡献
}yuu[2][N];
int s[N],tot;
bool isroot(int now){return ch[fa][0]==now||ch[fa][1]==now;}
int identity(int now){return ch[fa][1]==now;}
void connect(int f,int now,int typ){ch[fa=f][typ]=now;}
void Reverse(int now)
{
tag[now]^=1;
std::swap(yuu[0][now],yuu[1][now]);
}
void updata(int now)
{
for(int k=0;k<=1;k++)
{
yuu[k][now].is=(yuu[k][ls].is&&yuu[k][now].dat&&yuu[k][rs].is);
yuu[k][now].siz=yuu[k][ls].siz;
if(ls)
{
yuu[k][now].lef=yuu[k][ls].lef;
if(yuu[k][ls].is&&yuu[k][now].dat)
{
yuu[k][now].siz+=yuu[k][now].si+1;
if(yuu[k][rs].lef) yuu[k][now].siz+=yuu[k][rs].siz;
}
}
else
{
yuu[k][now].lef=yuu[k][now].dat;
yuu[k][now].siz+=yuu[k][now].si+1;
if(yuu[k][rs].lef) yuu[k][now].siz+=yuu[k][rs].siz;
}
}
}
void pushdown(int now)
{
if(tag[now])
{
if(ls) Reverse(ls);
if(rs) Reverse(rs);
tag[now]=0;
}
}
void Rotate(int now)
{
int p=fa,typ=identity(now);
connect(p,ch[now][typ^1],typ);
if(isroot(p)) connect(par[p],now,identity(p));
else fa=par[p];
connect(now,p,typ^1);
updata(p);
updata(now);
}
void splay(int now)
{
while(isroot(now)) s[++tot]=now,now=fa;
s[++tot]=now;
while(tot) pushdown(s[tot--]);
now=s[1];
for(;isroot(now);Rotate(now))
if(isroot(fa))
Rotate(identity(now)^identity(fa)?now:fa);
}
void access(int now)
{
for(int las=0;now;las=now,now=fa)
{
splay(now);
for(int k=0;k<=1;k++)
{
if(yuu[0][rs].lef)
yuu[k][now].si+=yuu[0][rs].siz;
if(yuu[0][las].lef)
yuu[k][now].si-=yuu[0][las].siz;
}
rs=las;
updata(now);
}
}
void dfs(int now,int f)
{
yuu[0][now].is=yuu[0][now].lef=yuu[0][now].dat=1;
//yuu[1][now].is=yuu[1][now].lef=yuu[1][now].dat=1;
for(int v,i=head[now];i;i=Next[i])
if((v=to[i])!=f)
par[v]=now,dfs(v,now),yuu[0][now].si+=yuu[0][v].siz;
yuu[0][now].siz=yuu[0][now].si+1;
yuu[1][now].si=yuu[0][now].si;
yuu[1][now].siz=yuu[0][now].siz;
}
void modi(int u)
{
access(u);
splay(u);
Reverse(u);
}
int query(int now)
{
pushdown(now);
if(!rs)
{
if(yuu[0][now].dat&&ls) return query(ls)+yuu[0][now].si+1;
return yuu[0][now].si+1;
}
if(yuu[0][rs].is)
{
int ret=yuu[0][now].si+1+yuu[0][rs].siz;
if(yuu[0][now].dat&&now!=1) ret+=query(ls);
return ret;
}
return query(rs);
}
int qry(int u)
{
access(u);
splay(u);
return ((yuu[0][u].dat&&u!=1)?query(ch[u][0]):0)+yuu[0][u].si+1;
}
int main()
{
freopen("scary.in","r",stdin);
freopen("scary.out","w",stdout);
yuu[1][1].dat=yuu[0][0].is=yuu[1][0].is=1;
read(n),read(m);
for(int u,v,i=1;i<n;i++) read(u),read(v),add(u,v),add(v,u);
dfs(1,0);
for(int op,u,v,i=1;i<=m;i++)
{
read(op);
if(op==1)
{
read(u),read(v);
modi(u),modi(v);
}
else
{
read(u);
printf("%d\n",qry(u));
}
}
return 0;
}

2019.3.25

Short But Scary 解题报告的更多相关文章

  1. 【LeetCode】392. Is Subsequence 解题报告(Python)

    [LeetCode]392. Is Subsequence 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/is-subseq ...

  2. CH Round #56 - 国庆节欢乐赛解题报告

    最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...

  3. 二模13day1解题报告

    二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...

  4. BZOJ 1051 最受欢迎的牛 解题报告

    题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4438  Solved: 2353[S ...

  5. 习题:codevs 2822 爱在心中 解题报告

    这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...

  6. 习题:codevs 1035 火车停留解题报告

    本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...

  7. 习题: codevs 2492 上帝造题的七分钟2 解题报告

    这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...

  8. 习题:codevs 1519 过路费 解题报告

    今天拿了这道题目练练手,感觉自己代码能力又增强了不少: 我的思路跟别人可能不一样. 首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这 ...

  9. NOIP2016提高组解题报告

    NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合

随机推荐

  1. IEC104协议规约解析

    一.四遥信息体基地址范围 104调度规约有1997年和2002年两个版本,在流程上没有什么变化,02版只是在97版上扩展了遥测.遥信等信息体基体址,区别如下: 类别 1997版基地址 2002版基地址 ...

  2. ARM汇编指令集_学习笔记(1)

    一.什么是ARM汇编? 运行在ARM处理器上的汇编语言就叫ARM汇编. C程序运行在X86平台,底层就是X86汇编:运行在ARM平台,底层就是ARM汇编.ARM汇编与X86汇编有显著区别. X86属于 ...

  3. 算法: 整数中1出现的次数(从1到n整数中1出现的次数)

    问题: 整数中1出现的次数(从1到n整数中1出现的次数) 问题:求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数? 为此他特别数了一下1~13中包含1的数字有1.10.11 ...

  4. gitbook 入门教程之导出电子书

    gitbook 既可以将源码文件单独输出,也可以仅输出单个文件,常见的导出电子书格式主要有三种(ePub, Mobi, PDF),而这三种格式都依赖于系统本身提供的 ebook-convert 工具. ...

  5. LeetCode算法题-Kth Largest Element in a Stream(Java实现)

    这是悦乐书的第296次更新,第315篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第164题(顺位题号是703).设计一个类来查找流中第k个最大元素.请注意,它是排序顺序 ...

  6. Springboot项目配置druid数据库连接池,并监控统计功能

    pom.xml配置依赖 <!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency> & ...

  7. centos7下git版本升级及gitlab安装

    centos系统自带的git版本过低,当使用git拉取.推送.克隆的时候可能会报错,常见的错误: error: The requested URL returned error: 401 Unauth ...

  8. web Deploy发布问题

    使用vs开发的时候,经常会发布项目.传统发布是登陆远程桌面.或ftp这些发布都有一定的麻烦.不能灵活的管理发布的文件.因此后来研究了web Deploy,研究之后发现是很不错的发布工具.这里把我使用w ...

  9. C# 里面swith的或者

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  10. sbt安裝與配置

    官方下載地址:https://www.scala-sbt.org/download.html?spm=a2c4e.11153940.blogcont238365.9.42d147e0iF8dhv 解压 ...