容易想到用dfs序转化为序列上的问题。考虑分块,对每块排序,修改时对于整块打上标记,边界暴力重构排序数组,询问时二分答案,这样k=sqrt(nlogn)时取最优复杂度nsqrt(nlogn)logn,离跑过去还差一点。二分答案这一部分看上去很难优化,考虑重构时不那么暴力,将要修改的和不要修改的部分分别从已排序数组中提出来,归并即可,这样k=sqrt(n)logn时取最优复杂度nsqrt(n)logn。尽管加了一些奇怪的卡常然而并没有什么卵用,bzoj上根本过不掉。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 100010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,len,p[N],deep[N],dfn[N],id[N],size[N],t,cnt,s;
int block,num,pos[N],L[N],R[N],lazy[N];
struct data{int to,nxt,len;
}edge[N];
struct data2
{
int i,x;
bool operator <(const data2&a) const
{
return x<a.x;
}
}a[N],u[N],v[N],w[N];
struct data3{int i,j,x,op;}Q[N];
void addedge(int x,int y,int z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;}
void dfs(int k)
{
size[k]=;dfn[k]=++cnt;id[cnt]=k;s=max(s,deep[k]);
for (int i=p[k];i;i=edge[i].nxt)
{
deep[edge[i].to]=deep[k]+edge[i].len;
dfs(edge[i].to);
size[k]+=size[edge[i].to];
}
}
void add(int k,int l,int r,int x)
{
int n=,m=;
for (int i=L[k];i<=R[k];i++)
if (a[i].i>=l&&a[i].i<=r) u[++n].i=a[i].i,deep[id[a[i].i]]+=x,u[n].x=a[i].x+x;
else v[++m]=a[i];
int p=,q=;
for (int i=L[k];i<=R[k];i++)
if (u[p].x<v[q].x&&p<=n||q>m) a[i]=u[p++];
else a[i]=v[q++];
}
int calc(int k,int l,int r)
{
if (pos[l]==pos[r])
{
int s=;
for (int i=l;i<=r;i++)
if (deep[id[i]]+lazy[pos[l]]<=k) s++;
return s;
}
else
{
int s=;
for (int i=pos[l]+;i<pos[r];i++)
s+=upper_bound(a+L[i],a+R[i]+,(data2){,k-lazy[i]})-a-L[i];
for (int i=l;i<=R[pos[l]];i++)
if (deep[id[i]]+lazy[pos[l]]<=k) s++;
for (int i=L[pos[r]];i<=r;i++)
if (deep[id[i]]+lazy[pos[r]]<=k) s++;
return s;
}
}
double complexity(double k,double q){return (m-q)*(n/k+*k)+q*log(s+(m-q)*(len+>>))/log()*(n/k*log(n)/log()+k);}
namespace segmenttree
{
int L[N<<],R[N<<],tree[N<<],lazy[N<<];
void build(int k,int l,int r)
{
L[k]=l,R[k]=r,lazy[k]=;
if (l==r) {tree[k]=deep[id[l]];return;}
int mid=l+r>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
tree[k]=max(tree[k<<],tree[k<<|]);
}
void update(int k,int x){tree[k]+=x,lazy[k]+=x;}
void down(int k){update(k<<,lazy[k]),update(k<<|,lazy[k]),lazy[k]=;}
void add(int k,int l,int r,int x)
{
if (L[k]==l&&R[k]==r) {update(k,x);return;}
if (lazy[k]) down(k);
int mid=L[k]+R[k]>>;
if (r<=mid) add(k<<,l,r,x);
else if (l>mid) add(k<<|,l,r,x);
else add(k<<,l,mid,x),add(k<<|,mid+,r,x);
tree[k]=max(tree[k<<],tree[k<<|]);
}
int query(int k,int l,int r)
{
if (L[k]==l&&R[k]==r) return tree[k];
if (lazy[k]) down(k);
int mid=L[k]+R[k]>>;
if (r<=mid) return query(k<<,l,r);
else if (l>mid) return query(k<<|,l,r);
else return max(query(k<<,l,mid),query(k<<|,mid+,r));
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4867.in","r",stdin);
freopen("bzoj4867.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read();len=read();
for (int i=;i<=n;i++)
{
int x=read(),y=read();
addedge(x,i,y);
}
dfs();segmenttree::build(,,n);
int qwq=;
for (int i=;i<=m;i++)
{
int op=read(),k=read(),x=read();
if (op==) qwq++;
Q[i].op=op,Q[i].i=dfn[k],Q[i].j=dfn[k]+size[k]-,Q[i].x=x;
}
block=;for (int i=;i<=n;i++) if (complexity(i,qwq)<complexity(block,qwq)) block=i;
num=(n-)/block+;
for (int i=;i<=num;i++)
{
L[i]=(i-)*block+,R[i]=min(n,i*block);
for (int j=L[i];j<=R[i];j++)
pos[j]=i,a[j].i=j,a[j].x=deep[id[j]];
sort(a+L[i],a+R[i]+);
}
for (int i=;i<=m;i++)
{
int l=Q[i].i,r=Q[i].j,x=Q[i].x;
if (Q[i].op==)
{
int left=,right=segmenttree::query(,l,r),ans=-;
while (left<=right)
{
int mid=left+right>>;
if (calc(mid,l,r)>=x) ans=mid,right=mid-;
else left=mid+;
}
printf("%d\n",ans);
}
else
{
segmenttree::add(,l,r,x);
if (pos[l]==pos[r]) add(pos[l],l,r,x);
else
{
for (int i=pos[l]+;i<pos[r];i++) lazy[i]+=x;
add(pos[l],l,R[pos[l]],x),add(pos[r],L[pos[r]],r,x);
}
}
}
return ;
}

BZOJ4867 Ynoi2017舌尖上的由乃(dfs序+分块)的更多相关文章

  1. BZOJ4867 : [Ynoi2017]舌尖上的由乃

    首先通过DFS序将原问题转化为序列上区间加.询问区间kth的问题. 考虑分块,设块大小为$K$,每块维护排序过后的$pair(值,编号)$. 对于修改,整块的部分可以直接打标记,而零碎的两块因为本来有 ...

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

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

  3. bzoj 4765 普通计算姬 dfs序 + 分块

    题目链接 Description "奋战三星期,造台计算机".小G响应号召,花了三小时造了台普通计算姬.普通计算姬比普通计算机要厉害一些.普通计算机能计算数列区间和,而普通计算姬能 ...

  4. 2016 ACM/ICPC Asia Regional Dalian Online 1010 Weak Pair dfs序+分块

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submissio ...

  5. 【HDU4366】【DFS序+分块】Successor

    Problem Description Sean owns a company and he is the BOSS.The other Staff has one Superior.every st ...

  6. HDU 4366 Successor(dfs序 + 分块)题解

    题意:每个人都有一个上司,每个人都有能力值和忠诚值,0是老板,现在给出m个询问,每次询问给出一个x,要求你找到x的所有直系和非直系下属中能力比他高的最忠诚的人是谁 思路:因为树上查询很麻烦,所以我们直 ...

  7. BZOJ 4765 普通计算姬 dfs序+分块+树状数组+好题!!!

    真是道好题...感到灵魂的升华... 按dfs序建树状数组,拿前缀和去求解散块: 按点的标号分块,分成一个个区间,记录区间子树和 的 总和... 具体地,需要记录每个点u修改后,对每一个块i的贡献,记 ...

  8. HDU - 4366 Successor DFS序 + 分块暴力 or 线段树维护

    给定一颗树,每个节点都有忠诚和能力两个参数,随意指定一个节点,要求在它的子树中找一个节点代替它,这个节点要满足能力值大于它,而且是忠诚度最高的那个. 首先,dfs一下,处理出L[i], R[i]表示d ...

  9. HDU4366 Successor【dfs序 分块】

    HDU4366 Successor 题意: 给出一棵根为\(1\)的树,每个点有两个权值\(x,y\),每次询问一个点的子树中\(x\)比这个点的\(x\)大且\(y\)值最大的那个点 题解: 如果以 ...

随机推荐

  1. 成都Uber优步司机奖励政策(2月26日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  2. COGS 2199. [HZOI 2016] 活动投票

    2199. [HZOI 2016] 活动投票 ★★   输入文件:hztp.in   输出文件:hztp.out   简单对比时间限制:0.5 s   内存限制:2 MB [题目描述] 衡中活动很多, ...

  3. datawindow自动换行打印,需结合该函数一起使用

    1.设置 具体步骤如下:     1) 在DataWindow Painter中打开此DataWindow对象.    2) 在需设定自动折行的列上双击鼠标, 弹开此列的属性窗口.    3) 选择P ...

  4. VS中添加新项 数据选项卡下没有ADO.NET实体数据模型解决方案

    第一种:C:\ProgramData下面搜索EFTools找到你vs对应版本的EFTools.msi 先remove 然后再Install 重启电脑再看 第二种:如果意外地删除了 Visual Stu ...

  5. 项目实战:BBS+Blog项目开发

    01-博客系统之功能需求 02-博客系统之表结构设计1 03-博客系统之表结构设计2 04-博客系统之表结构设计3 05-博客系统之表结构设计4 06-博客系统之表机构设计5 07-博客系统之创建系统 ...

  6. 373. Partition Array by Odd and Even【LintCode java】

    Description Partition an integers array into odd number first and even number second. Example Given  ...

  7. django 连接mysql报错

    原因: 问题1. 即从mysql5.7版本之后,默认采用了caching_sha2_password验证方式. 问题2.  然后在执行 python manage.py makemigrations依 ...

  8. kvm网络虚拟化

    网络虚拟化是虚拟化技术中最复杂的部分,学习难度最大. 但因为网络是虚拟化中非常重要的资源,所以再硬的骨头也必须要把它啃下来. 为了让大家对虚拟化网络的复杂程度有一个直观的认识,请看下图 这是 Open ...

  9. JavaScript筑基篇(三)->JS原型和原型链的理解

    删除理由:很久以前写的,当时理解不够深入,这样描述反而看起来更复杂了.因此就删掉,免得误人子弟! 可以看看另一篇文章:[如何继承Date对象?由一道题彻底弄懂JS继承.](http://www.cnb ...

  10. redis 编译安装错误问题

    编译redis安装的时候报错如下: make[1]: [persist-settings] Error 2 (ignored) CC adlist.o/bin/sh: cc: command not ...