「HNOI2016」网络 解题报告
「HNOI2016」网络
我有一个绝妙的可持久化树套树思路,可惜的是,它的空间是\(n\log^2 n\)的...
注意到对一个询问,我们可以二分答案
然后统计经过这个点大于当前答案的路径条数,如果这个路径条数等于大于当前答案的所有路径条数,那么这个答案是不行的。
关于链修改单点询问,可以树状数组维护dfs序,然后每次修改链去差分修改
然后把二分答案拿到整体二分上去就可以了
Code:
#include <cstdio>
#include <cctype>
#include <cmath>
#include <algorithm>
const int N=3e5+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 dfn[N],low[N],dep[N],f[18][N],dfsclock;
int n,m,q,s[N],ans[N];
struct koito_yuu{int u,v,x,lca;}yuu[N],yuul[N],yuur[N];
void dfs(int now)
{
dfn[now]=++dfsclock;
dep[now]=dep[f[0][now]]+1;
for(int i=1;f[i-1][now];i++) f[i][now]=f[i-1][f[i-1][now]];
for(int v,i=head[now];i;i=Next[i])
if((v=to[i])!=f[0][now])
f[0][v]=now,dfs(v);
low[now]=dfsclock;
}
int LCA(int x,int y)
{
if(dep[x]<dep[y]) std::swap(x,y);
for(int i=17;~i;i--)
if(dep[f[i][x]]>=dep[y])
x=f[i][x];
if(x==y) return x;
for(int i=17;~i;i--)
if(f[i][x]!=f[i][y])
x=f[i][x],y=f[i][y];
return f[0][x];
}
void modify(int x,int d){while(x&&x<=n)s[x]+=d,x+=x&-x;}
int query(int x){int ret=0;while(x)ret+=s[x],x-=x&-x;return ret;}
void modi(int u,int v,int lca,int d)
{
modify(dfn[u],d);
modify(dfn[v],d);
modify(dfn[lca],-d);
modify(dfn[f[0][lca]],-d);
}
int qry(int u)
{
return query(low[u])-query(dfn[u]-1);
}
void Divide(int l,int r,int L,int R)
{
if(l>r) return;
if(L==R)
{
for(int i=l;i<=r;i++)
if(!yuu[i].v)
ans[yuu[i].x]=L;
return;
}
int Mid=L+R>>1;
int lp=0,rp=0,cnt=0;
for(int i=l;i<=r;i++)
{
if(yuu[i].v)
{
if(abs(yuu[i].x)>Mid)
{
yuur[++rp]=yuu[i];
if(yuu[i].x>0) modi(yuu[i].u,yuu[i].v,yuu[i].lca,1),++cnt;
else modi(yuu[i].u,yuu[i].v,yuu[i].lca,-1),--cnt;
}
else yuul[++lp]=yuu[i];
}
else
{
int ct=qry(yuu[i].u);
if(ct==cnt) yuul[++lp]=yuu[i];
else yuur[++rp]=yuu[i];
}
}
for(int i=l;i<=r;i++)
if(yuu[i].v&&abs(yuu[i].x)>Mid)
modi(yuu[i].u,yuu[i].v,yuu[i].lca,yuu[i].x>0?-1:1);
for(int i=1;i<=lp;i++) yuu[i+l-1]=yuul[i];
for(int i=1;i<=rp;i++) yuu[i+l+lp-1]=yuur[i];
Divide(l,l+lp-1,L,Mid),Divide(l+lp,r,Mid+1,R);
}
int main()
{
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);
for(int typ,t,i=1;i<=m;i++)
{
read(typ);
if(typ==0) read(yuu[i].u),read(yuu[i].v),read(yuu[i].x),yuu[i].lca=LCA(yuu[i].u,yuu[i].v);
else if(typ==1) read(t),yuu[i]=yuu[t],yuu[i].x=-yuu[i].x;
else read(yuu[i].u),yuu[i].x=++q;
}
Divide(1,m,0,(int)(1e9));
for(int i=1;i<=q;i++) printf("%d\n",ans[i]?ans[i]:-1);
return 0;
}
2019.3.9
「HNOI2016」网络 解题报告的更多相关文章
- 「HNOI2016」树 解题报告
「HNOI2016」树 事毒瘤题... 我一开始以为每次把大树的子树再接给大树,然后死活不知道咋做,心想怕不是个神仙题哦 然后看题解后才发现是把模板树的子树给大树,虽然思维上难度没啥了,但是还是很难写 ...
- 「HNOI2016」序列 解题报告
「HNOI2016」序列 有一些高妙的做法,懒得看 考虑莫队,考虑莫队咋移动区间 然后你在区间内部找一个最小值的位置,假设现在从右边加 最小值左边区间显然可以\(O(1)\),最小值右边的区间是断掉的 ...
- 「HNOI2016」最小公倍数 解题报告
「HNOI2016」最小公倍数 考虑暴力,对每个询问,处理出\(\le a,\le b\)的与询问点在一起的联通块,然后判断是否是一个联通块,且联通块\(a,b\)最大值是否满足要求. 然后很显然需要 ...
- 「SDOI2014」Lis 解题报告
「SDOI2014」Lis 题目描述 给定序列 \(A\),序列中的每一项 \(A_i\) 有删除代价 \(B_i\) 和附加属性 \(C_i\). 请删除若干项,使得 \(A\) 的最长上升子序列长 ...
- 「ZJOI2016」旅行者 解题报告
「ZJOI2016」旅行者 对网格图进行分治. 每次从中间选一列,然后枚举每个这一列的格子作为起点跑最短路,进入子矩形时把询问划分一下,有点类似整体二分 至于复杂度么,我不会阿 Code: #incl ...
- 「HAOI2018」染色 解题报告
「HAOI2018」染色 是个套路题.. 考虑容斥 则恰好为\(k\)个颜色恰好为\(c\)次的贡献为 \[ \binom{m}{k}\sum_{i\ge k}(-1)^{i-k}\binom{m-k ...
- 「SCOI2016」围棋 解题报告
「SCOI2016」围棋 打CF后困不拉基的,搞了一上午... 考虑直接状压棋子,然后发现会t 考虑我们需要上一行的状态本质上是某个位置为末尾是否可以匹配第一行的串 于是状态可以\(2^m\)压住了, ...
- 「SCOI2016」妖怪 解题报告
「SCOI2016」妖怪 玄妙...盲猜一个结论,然后过了,事后一证,然后假了,数据真水 首先要最小化 \[ \max_{i=1}^n (1+k)x_i+(1+\frac{1}{k})y_i \] \ ...
- 「SCOI2016」美味 解题报告
「SCOI2016」美味 状态极差无比,一个锤子题目而已 考虑每次对\(b\)和\(d\)求\(c=d \ xor \ (a+b)\)的最大值,因为异或每一位是独立的,所以我们可以尝试按位贪心. 如果 ...
随机推荐
- 使用junit测试
package creeper; import java.util.Scanner; public class size { private static int intercePosition = ...
- hadoop和java 配置环境变量的的tar
第一步:打开工具上传tar包 如下图 第二步:在文件路径下查看是否上传成功 第三步:解压tar包 tar -zxvf hadoop.2.6.5.tar.gz 第四步:配置环 ...
- C99标准的柔性数组 (Flexible Array)
[什么是柔性数组(Fliexible Array)] 柔性数组在C99中的定义是: 6.7.2.1 Structure and union specifiers As a special case, ...
- 快速理解Git结构
git pull:拉取远程服务器最新代码到本地(会自动merge) git add:将本地代码添加到暂存区 git commit:将暂存区的所有内容提交到当前分支(git会自动为我们创建第一个分支 ...
- “耐撕”团队 2016.03.31 站立会议
1. 时间: 19:30--19:50 共计20分钟. 2. 成员: Z 郑蕊 * 组长 (博客:http://www.cnblogs.com/zhengrui0452/), P 濮成林(博客:ht ...
- Linux基础学习笔记5-软件管理
包管理器 二进制应用程序的组成部分: 二进制文件.库文件.配置文件.帮助文件 程序包管理器: debian:deb文件.dpkg包管理器 redhat:rpm文件.rpm包管理器 rpm:Redhat ...
- python函数、模块、包
一.函数 定义函数: def fun_name(para_list): coding def fun_name(para_list): coding return xxx 使用函数,fun_name( ...
- centos安装Tesseract
yum安装(推荐) yum search tesseract yum install tesseract.x86_64 -y pip3 install pytesseract pip3 install ...
- SSH的使用
1.如何设置SSH的超时时间 使用SSH客户端软件登录linux服务器后,执行 echo $TMOUT可以查看SSH链接超时时间: 使用vim /etc/profile可以编辑配置页面 修改TMOUT ...
- Visual Studio for Mac中的ASP.NET Core
所以你们都听到了#Build 2017的消息,Mac上的Visual Studio已经被完全发布,是一般的.为了庆祝这个版本,我将在我的Mac上写几篇关于构建一些不同的.net应用的帖子. 正如你已经 ...