「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」网络 解题报告的更多相关文章

  1. 「HNOI2016」树 解题报告

    「HNOI2016」树 事毒瘤题... 我一开始以为每次把大树的子树再接给大树,然后死活不知道咋做,心想怕不是个神仙题哦 然后看题解后才发现是把模板树的子树给大树,虽然思维上难度没啥了,但是还是很难写 ...

  2. 「HNOI2016」序列 解题报告

    「HNOI2016」序列 有一些高妙的做法,懒得看 考虑莫队,考虑莫队咋移动区间 然后你在区间内部找一个最小值的位置,假设现在从右边加 最小值左边区间显然可以\(O(1)\),最小值右边的区间是断掉的 ...

  3. 「HNOI2016」最小公倍数 解题报告

    「HNOI2016」最小公倍数 考虑暴力,对每个询问,处理出\(\le a,\le b\)的与询问点在一起的联通块,然后判断是否是一个联通块,且联通块\(a,b\)最大值是否满足要求. 然后很显然需要 ...

  4. 「SDOI2014」Lis 解题报告

    「SDOI2014」Lis 题目描述 给定序列 \(A\),序列中的每一项 \(A_i\) 有删除代价 \(B_i\) 和附加属性 \(C_i\). 请删除若干项,使得 \(A\) 的最长上升子序列长 ...

  5. 「ZJOI2016」旅行者 解题报告

    「ZJOI2016」旅行者 对网格图进行分治. 每次从中间选一列,然后枚举每个这一列的格子作为起点跑最短路,进入子矩形时把询问划分一下,有点类似整体二分 至于复杂度么,我不会阿 Code: #incl ...

  6. 「HAOI2018」染色 解题报告

    「HAOI2018」染色 是个套路题.. 考虑容斥 则恰好为\(k\)个颜色恰好为\(c\)次的贡献为 \[ \binom{m}{k}\sum_{i\ge k}(-1)^{i-k}\binom{m-k ...

  7. 「SCOI2016」围棋 解题报告

    「SCOI2016」围棋 打CF后困不拉基的,搞了一上午... 考虑直接状压棋子,然后发现会t 考虑我们需要上一行的状态本质上是某个位置为末尾是否可以匹配第一行的串 于是状态可以\(2^m\)压住了, ...

  8. 「SCOI2016」妖怪 解题报告

    「SCOI2016」妖怪 玄妙...盲猜一个结论,然后过了,事后一证,然后假了,数据真水 首先要最小化 \[ \max_{i=1}^n (1+k)x_i+(1+\frac{1}{k})y_i \] \ ...

  9. 「SCOI2016」美味 解题报告

    「SCOI2016」美味 状态极差无比,一个锤子题目而已 考虑每次对\(b\)和\(d\)求\(c=d \ xor \ (a+b)\)的最大值,因为异或每一位是独立的,所以我们可以尝试按位贪心. 如果 ...

随机推荐

  1. Vector源码分析

    Vector与ArrayList底层实现基本类似,底层都是用数组实现的,最大的不同是Vector是线程安全的.ArrayList源码分析请参考ArrayList源码分析 一.源码分析 基于jdk1.7 ...

  2. git repository description

    Git - Plumbing and Porcelainhttps://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain gith ...

  3. Centos下启动和关闭MySQL

    https://blog.csdn.net/gghh2015/article/details/78281585

  4. Ubuntu 12.04 安装socks5代理服务器dante-server

    dante-server是一个很好的socks4/5代理服务器软件. 使用apt-get安装   1 apt-getinstall dante-server 添加一个用户   1 2 useradd ...

  5. jenkins 插件介绍

    1.jenkins 利用maven编译,打包,所需插件:Maven Integration: Maven集成插件这个插件提供了Jenkins和Maven的深度集成,无论是好还是坏:项目之间的自动触发取 ...

  6. 解决.Net Mvc跨域请求问题

    针对ASP.NET MVC和ASP.NET Web API两种项目类型 1.针对ASP.NET MVC,只需要在web.config中添加如下的内容即可 <system.webServer> ...

  7. DAY04、流程控制if、while、for

    一.if 判断 语法一: if 条件: # 以下是上一条if 的子代码块 print(子代码1) print(子代码2) print(子代码3) 示例: # 路边飘过一个生物,要不要表白? sex = ...

  8. 集合之HashSet(含JDK1.8源码分析)

    一.前言 我们已经分析了List接口下的ArrayList和LinkedList,以及Map接口下的HashMap.LinkedHashMap.TreeMap,接下来看的是Set接口下HashSet和 ...

  9. layer弹层基本参数初尝试

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  10. jdbc一点小笔记

    JDBC的常用接口的步骤, 1使用Driver或者Class.forName()进行注册驱动: 2使用DriverManager进行获取数据库的链接.使用Connection获取语句对象.使用语句对象 ...