BZOJ_4867_[Ynoi2017]舌尖上的由乃_分块+dfs序
BZOJ_4867_[Ynoi2017]舌尖上的由乃_分块+dfs序
Description
Input
Output
Sample Input
1 3
2 3
1 1 3
2 3 3
1 1 3
2 1 2
1 1 3
Sample Output
9
11
HINT
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
#define RR register
inline char nc() {
static char buf[100000],*p1,*p2;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int rd() {
RR int x=0;RR char s=nc();
while(s<'0'||s>'9') s=nc();
while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=nc();
return x;
}
#define N 100500
int head[N],to[N],nxt[N],val[N],cnt,dfn[N],son[N],L[N],R[N],block,dis[N],n,m,pos[N],mx,t[N],more[N],size,fa[N],tot;
struct A {
int v,id;
}a[N],b[N],c[N];
inline bool cmp1(const A &x,const A &y) {
return x.v<y.v;
}
inline void add(int u,int v,int w) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; val[cnt]=w;
}
void dfs(int x) {
RR int i; dfn[x]=++tot; a[tot].v=dis[x]; a[tot].id=tot;
for(i=head[x];i;i=nxt[i]) {
dis[to[i]]=dis[x]+val[i];
dfs(to[i]);
}
son[x]=tot;
}
inline void update(int l,int r,int v) {
RR int p=pos[l],q=pos[r],i,j,k;
RR int lb=0,lc=0;
if(p==q) {
for(i=L[p];i<=R[p];i++) {
if(a[i].id<=r&&a[i].id>=l) b[++lb]=a[i],b[lb].v+=v;
else c[++lc]=a[i];
}
i=1; j=1; k=L[p];
while(i<=lb&&j<=lc) {
if(b[i].v<=c[j].v) a[k++]=b[i++];
else a[k++]=c[j++];
}
while(i<=lb) a[k++]=b[i++];
while(j<=lc) a[k++]=c[j++];
}else {
for(i=p+1;i<q;i++) more[i]+=v; lb=0,lc=0;
for(i=L[p];i<=R[p];i++) {
if(a[i].id>=l) b[++lb]=a[i],b[lb].v+=v;
else c[++lc]=a[i];
}
i=1; j=1; k=L[p];
while(i<=lb&&j<=lc) {
if(b[i].v<=c[j].v) a[k++]=b[i++];
else a[k++]=c[j++];
}
while(i<=lb) a[k++]=b[i++];
while(j<=lc) a[k++]=c[j++]; lb=0; lc=0;
for(i=L[q];i<=R[q];i++) {
if(a[i].id<=r) b[++lb]=a[i],b[lb].v+=v;
else c[++lc]=a[i];
}
i=1; j=1; k=L[q];
while(i<=lb&&j<=lc) {
if(b[i].v<=c[j].v) a[k++]=b[i++];
else a[k++]=c[j++];
}
while(i<=lb) a[k++]=b[i++];
while(j<=lc) a[k++]=c[j++];
}
}
inline int search(int l,int r,int x) {
RR int tmp=l,p=pos[l]; r++;
x-=more[p];
while(l<r) {
int mid=(l+r)>>1;
if(a[mid].v<=x) l=mid+1;
else r=mid;
}
return l-tmp;
}
inline int findt(int x) {
RR int l=1,r=t[0]+1,mid;
while(l<r) {
mid=(l+r)>>1;
if(t[mid]<=x) l=mid+1;
else r=mid;
}
return l-1;
}
inline int query(int x,int y,int k) {
if(y-x+1<k) return -1;
RR int p=pos[x],q=pos[y],i,j;
if(p==q) {
t[0]=0;
for(i=L[p];i<=R[p];i++) {
if(a[i].id>=x&&a[i].id<=y) t[++t[0]]=a[i].v+more[p];
}
}else {
t[0]=0;
RR int lb=0,lc=0;
for(i=L[p];i<=R[p];i++) {
if(a[i].id>=x) b[++lb]=a[i],b[lb].v+=more[p];
}
for(i=L[q];i<=R[q];i++) {
if(a[i].id<=y) c[++lc]=a[i],c[lc].v+=more[q];
}
i=1; j=1;
while(i<=lb&&j<=lc) {
if(b[i].v<=c[j].v) t[++t[0]]=b[i++].v;
else t[++t[0]]=c[j++].v;
}
while(i<=lb) t[++t[0]]=b[i++].v;
while(j<=lc) t[++t[0]]=c[j++].v;
}
RR int l=0,r=mx+1,mid,re;
while(l<r) {
mid=(l+r)>>1; re=0;
if(t[0]) re+=findt(mid);
for(i=p+1;i<q;i++) re+=search(L[i],R[i],mid);
if(re>=k) r=mid;
else l=mid+1;
}
return l;
}
int main() {
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
RR int kitty,opt;
n=rd(); m=rd(); kitty=rd();
RR int i,x,y,j;
// int ln=n,lg=1;
// while(ln) lg++,ln>>=1;
for(i=2;i<=n;i++) {
x=rd(); y=rd(); add(x,i,y);
}
// size=((int)ceil(sqrt(n)))*(lg);
// printf("%d\n",size);return 0;
size=3700;
dfs(1);
block=n/size;
for(i=1;i<=block;i++) {
L[i]=R[i-1]+1; R[i]=i*size;
sort(a+L[i],a+R[i]+1,cmp1);
mx=max(mx,a[R[i]].v);
for(j=L[i];j<=R[i];j++) pos[j]=i;
}
if(R[block]!=n) {
block++; L[block]=R[block-1]+1; R[block]=n;
sort(a+L[block],a+n+1,cmp1);
for(i=L[block];i<=n;i++) pos[i]=block;
mx=max(mx,a[n].v);
}
while(m--) {
opt=rd(); x=rd(); y=rd();
if(opt==1) {
printf("%d\n",query(dfn[x],son[x],y));
}else {
update(dfn[x],son[x],y); mx+=y;
}
}
return 0;
}
BZOJ_4867_[Ynoi2017]舌尖上的由乃_分块+dfs序的更多相关文章
- BZOJ_4765_普通计算姬_分块+dfs序+树状数组
BZOJ_4765_普通计算姬_分块 Description "奋战三星期,造台计算机".小G响应号召,花了三小时造了台普通计算姬.普通计算姬比普通计算机要厉害一些 .普通计算机能 ...
- BZOJ4867 : [Ynoi2017]舌尖上的由乃
首先通过DFS序将原问题转化为序列上区间加.询问区间kth的问题. 考虑分块,设块大小为$K$,每块维护排序过后的$pair(值,编号)$. 对于修改,整块的部分可以直接打标记,而零碎的两块因为本来有 ...
- BZOJ4867 Ynoi2017舌尖上的由乃(dfs序+分块)
容易想到用dfs序转化为序列上的问题.考虑分块,对每块排序,修改时对于整块打上标记,边界暴力重构排序数组,询问时二分答案,这样k=sqrt(nlogn)时取最优复杂度nsqrt(nlogn)logn, ...
- (原创)舌尖上的c++--相逢
引子 前些时候,我在群里出了一道题目:将变参的类型连接在一起作为字符串并返回出来,要求只用函数实现,不能借助于结构体实现.用结构体来实现比较简单: template<typename... Ar ...
- 舌尖上的硬件:CPU/GPU芯片制造解析(高清)(组图)
一沙一世界,一树一菩提,我们这个世界的深邃全部蕴藏于一个个普通的平凡当中.小小的厨房所容纳的不仅仅是人们对味道的情感,更有推动整个世界前进的动力.要想理解我们的世界,有的时候只需要细细品味一下我们所喜 ...
- BZOJ_3252_攻略_线段树+dfs序
BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...
- BZOJ_3729_Gty的游戏_博弈论+splay+dfs序
BZOJ_3729_Gty的游戏_博弈论+splay+dfs序 Description 某一天gty在与他的妹子玩游戏. 妹子提出一个游戏,给定一棵有根树,每个节点有一些石子,每次可以将不多于L的石子 ...
- BZOJ_2821_作诗(Poetize)_分块
BZOJ_2821_作诗(Poetize)_分块 Description 神犇SJY虐完HEOI之后给傻×LYD出了一题:SHY是T国的公主,平时的一大爱好是作诗.由于时间紧迫,SHY作完诗 之后还要 ...
- BZOJ_2434_[NOI2011]_阿狸的打字机_(AC自动机+dfs序+树状数组)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=2434 给出\(n\)个字符串,\(m\)个询问,对于第\(i\)个询问,求第\(x_i\)个字 ...
随机推荐
- aside元素
aside元素用来表示当前页面或文章的附属信息部分,它可以包含与当前页面或主要内容相关的引用.侧边栏.广告.导航条,以及其他类似的有别于主要内容的部分. aside元素主要有以下两种使用方法: 1.包 ...
- Java语言概论
第1章 ■ Java的发展简史及特点 ■ J2SDK的下载与安装 ■ Java应用程序的编写 ■ Eclipse的下载及使用 ■ 正确安装使用J2SDK ■ 使用记 ...
- 【Web页面测试】测试点和测试用例
1. 需求符合度测试 1. 各级菜单名称显示是否按照需求说明书规定的设计,并且没有遗漏和多余 2. 各级菜单所完成的功能是否按照需求说明书规定的设计,并且没有遗漏和多余 3. 各级菜单的操作顺序和操作 ...
- Spring温故而知新 - bean的装配(续)
按条件装配bean 就是当满足特定的条件时Spring容器才创建Bean,Spring中通过@Conditional注解来实现条件化配置bean package com.sl.ioc; import ...
- Day8 接口与归一化设计
接口:在程序的使用中,我不能把程序的主体直接提供给使用者,一般是提供一个接口. 为什么要使用接口: 1,接口提取了一群共同的函数,可以把接口当做一个函数的集合. 2,让子类去实现接口中的函数. 归一化 ...
- Python教程大纲
缘起:最近想在部门推Python语言,写这个blog主要就是个教程大纲,之前先列出一些资源:Python历史:http://www.docin.com/p-53019548.html ...
- 畅通工程-HZNU寒假集训
畅通工程 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅通工程"的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只 ...
- Visual Studio Live Share不完全指北
Visual Studio Live Share是什么? 是VS的一个实时协作开发的扩展工具. github地址:https://github.com/MicrosoftD...文档地址:https: ...
- jvm GC
JavaGC.新生代.老年代 Java 中的堆是 JVM所管理的最大的一块内存空间,主要用于存放各种类的实例对象. 在 Java 中,堆被划分成两个不同的区域:新生代 ( Young ).老年代 ( ...
- Thymeleaf中each标签遍历list如何获取index
<tr th:each="user,userStat:${users}">userStat是状态变量,有 index,count,size,current,even,o ...