首先通过DFS序将原问题转化为序列上区间加、询问区间kth的问题。

考虑分块,设块大小为$K$,每块维护排序过后的$pair(值,编号)$。

对于修改,整块的部分可以直接打标记,而零碎的两块因为本来有序,故可以按照修改区间将其分离成两个有序序列$A$(不在修改区间)和$B$(在修改区间)。

对$B$每个值都加上一个常数,再与$A$归并排序,即可在$O(K)$的时间内修改零碎的两块。

对于查询,首先将零碎的两块用同样的方法分离出来,然后二分答案,在每个整块二分查找个数即可,时间复杂度$O(\frac{n}{K}\log^2n)$。

当$K$取$\sqrt{n}\log n$时取得最优复杂度$O(n\sqrt{n}\log n)$。

#include<cstdio>
#include<algorithm>
using namespace std;
typedef pair<int,int>P;
const int N=100010,K=12,M=(N>>K)+5,BUF=6000000;
char Buf[BUF],*buf=Buf;
int n,m,i,lim,op,x,y,g[N],w[N],nxt[N],stq[N],enq[N],dfn;
int block,st[M],en[M],tag[M];P a[N<<1];
inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;}
inline void add(int x,int y,int z){w[y]=z;nxt[y]=g[x];g[x]=y;}
void dfs(int x,int y){
stq[x]=++dfn;
a[dfn]=P(y,dfn);
for(int i=g[x];i;i=nxt[i])dfs(i,y+w[i]);
enq[x]=dfn;
}
inline void change(int o,int l,int r,int p){
static P A[N],B[N];
int ca=0,cb=0,i,j,k=st[o];
for(i=st[o];i<=en[o];i++)if(a[i].second<l||a[i].second>r)A[++ca]=a[i];else B[++cb]=a[i],B[cb].first+=p;
i=j=1;
while(i<=ca&&j<=cb)a[k++]=A[i]<B[j]?A[i++]:B[j++];
while(i<=ca)a[k++]=A[i++];
while(j<=cb)a[k++]=B[j++];
}
inline void modify(int x,int y,int p){
int X=x>>K,Y=y>>K,i;
for(i=X+1;i<Y;i++)tag[i]+=p;
change(X,x,y,p);
if(X<Y)change(Y,x,y,p);
}
inline int ask(int o,int p){
int l=st[o],r=en[o],mid,t=l-1;
if(l>r)return 0;
p-=tag[o];
while(l<=r)if(a[mid=(l+r)>>1].first<=p)l=(t=mid)+1;else r=mid-1;
return t-st[o]+1;
}
inline int kth(int x,int y,int k){
if(k>y-x+1)return -1;
int X=x>>K,Y=y>>K,i,s=n+1,e=n;
tag[block+1]=tag[X];
for(i=st[X];i<=en[X];i++)if(a[i].second>=x&&a[i].second<=y)a[++e]=a[i];
st[block+1]=s,en[block+1]=e;
s=e+1;
if(X<Y){
tag[block+2]=tag[Y];
for(i=st[Y];i<=en[Y];i++)if(a[i].second<=y)a[++e]=a[i];
}
st[block+2]=s,en[block+2]=e;
int l=0,r=lim,mid,t,ans;
while(l<=r){
mid=(l+r)>>1;
t=ask(block+1,mid)+ask(block+2,mid);
for(i=X+1;i<Y&&t<k;i++)t+=ask(i,mid);
if(t>=k)r=(ans=mid)-1;else l=mid+1;
}
return ans;
}
int main(){
fread(Buf,1,BUF,stdin);read(n),read(m),read(x);
for(i=2;i<=n;i++)read(x),read(y),add(x,i,y),lim+=y;
dfs(1,0);
block=n>>K;
for(i=1;i<=n;i++)en[i>>K]=i;
for(i=n;i;i--)st[i>>K]=i;
for(i=0;i<=block;i++)sort(a+st[i],a+en[i]+1);
while(m--){
read(op),read(x),read(y);
if(op==1)printf("%d\n",kth(stq[x],enq[x],y));else modify(stq[x],enq[x],y),lim+=y;
}
return 0;
}

  

BZOJ4867 : [Ynoi2017]舌尖上的由乃的更多相关文章

  1. BZOJ4867 Ynoi2017舌尖上的由乃(dfs序+分块)

    容易想到用dfs序转化为序列上的问题.考虑分块,对每块排序,修改时对于整块打上标记,边界暴力重构排序数组,询问时二分答案,这样k=sqrt(nlogn)时取最优复杂度nsqrt(nlogn)logn, ...

  2. BZOJ_4867_[Ynoi2017]舌尖上的由乃_分块+dfs序

    BZOJ_4867_[Ynoi2017]舌尖上的由乃_分块+dfs序 Description 由乃为了吃到最传统最纯净的美食,决定亲自开垦一片菜园.现有一片空地,由乃已经规划n个地点准备种上蔬菜.最新 ...

  3. (原创)舌尖上的c++--相逢

    引子 前些时候,我在群里出了一道题目:将变参的类型连接在一起作为字符串并返回出来,要求只用函数实现,不能借助于结构体实现.用结构体来实现比较简单: template<typename... Ar ...

  4. 舌尖上的硬件:CPU/GPU芯片制造解析(高清)(组图)

    一沙一世界,一树一菩提,我们这个世界的深邃全部蕴藏于一个个普通的平凡当中.小小的厨房所容纳的不仅仅是人们对味道的情感,更有推动整个世界前进的动力.要想理解我们的世界,有的时候只需要细细品味一下我们所喜 ...

  5. 舌尖上的javascript数组和字符串基本操作

    Javascript数组基本操作 Javascript中的数组是一种特殊的对象,用来表示偏移量的索引是该对象的属性,索引可能是整数,然而这些数字索引在内部被转换为字符串类型,这是因为javascrip ...

  6. python基础-文件操作

    一.文件操作 打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文件句柄对该文件操作. 打开文件的模式有: r ,只读模式[默认模式,文件必须存在,不存在则抛出异 ...

  7. Python之路,Day3 - Python基础3

    一.文件操作 对文件操作流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 现有文件如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  8. Python之路第一课Day3--随堂笔记(文件操作)

    一.集合的介绍 1.集合操作 集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之前的交集.差集.并集等关系 常用操作 s = se ...

  9. Python之路第一课Day2--随堂笔记

    入门知识拾遗 一.bytes类型 bytes转二进制然后转回来 msg="张杨" print(msg) print(msg.encode("utf-8")) p ...

随机推荐

  1. AR 前言

    LBS 基于位置的服务,是指通过电信移动运营商的无线电通讯网络或外部定位方式,获取移动终端用户的位置信息,在GIS平台的支持下,为用户提供相应服务的一种增值业务. 它包括两层含义:首先是确定移动设备或 ...

  2. VMware 虚拟机 Ubuntu 系统执行 ifconfig 命令 eth0没有IP地址(intet addr、Bcast、Mask) 解决:UP BROADCAST MULTICAST 问题

    VMware 虚拟机 ifconfig没有net_addr地址.Bcast.Mask的解决方法 使用时间长的虚拟机,会莫名其妙的连接不上网 在终端中,使用ifconfig命令查看Ubuntu系统的IP ...

  3. windows上编译boost库

    要用xx库,编译boost时就指定--with-xx.例如: # 下载并解压boost_1.58 # 进入boost_1.58目录 bjam.exe toolset=msvc-14.0 --build ...

  4. thinkphp5.0和thinkphp3.2的区别不同之处

    先看目录结构: thinkphp 5.0的目录结构, 文档:https://www.kancloud.cn/manual/thinkphp5/118008 project 应用部署目录 ├─appli ...

  5. 迅速上手:使用taro构建微信小程序基础教程

    前言 由于微信小程序在开发上不能安装npm依赖,和开发流程上也饱受诟病:Taro 是由京东·凹凸实验室(aotu.io)倾力打造的 多端开发解决方案,它的api基于react,在本篇文章中主要介绍了使 ...

  6. WPF 对控件进行截图且不丢失范围(转载)

    原文:Taking WPF “Screenshots” I was recently working on a Surface project at Microsoft (that will be s ...

  7. 期货大赛项目|二,DAL详解

    接口层就不重点讲述了,直接DAL层 DAL层 using System; using System.Collections.Generic; using System.Linq; using Syst ...

  8. ghithub中PHPOffice/PHPWord的学习

    1.概念:PHPWord是用纯PHP提供了一组类写入和从不同的文档格式的文件阅读库.PHPWord的当前版本支持微软的Office Open XML(OOXML或处理OpenXML),用于Office ...

  9. vue中使用axios最详细教程

    前提条件:vue-cli 项目 安装: npm npm 在main.js导入: // 引入axios,并加到原型链中 import axios from 'axios'; Vue.prototype. ...

  10. F(x) 数位dp

    Problem Description For a decimal number x with n digits (AnAn-1An-2 ... A2A1), we define its weight ...