loj6046 「雅礼集训 2017 Day8」爷
最近遇到几个分块题,我发现我一遇到分块题就死活构造不出来
不对,明明是,遇到数据结构题,就死活构造不出来。
所以我就找了几个分块题做做。
其实分块,树上的,很多都是先求一个dfs序,或者树剖,用一个log的代价或者没有多余的代价变成序列上的东西
树上的东西想到dfs序和树剖不是套路么……
很多不好维护的东西,都可以用分块来做,诶这不是我以前说过的么。
这道题,如果分块,那么按照套路,块内就可以排序,我们可以二分一个答案,然后在块内二分。
算了算复杂度,2个log,一个根号,不是很优秀的样子。
而题面上说$k \leq 10$,肯定有阴谋!
我们想,如果一个块内,元素最小最大值之差不大,我们就可以直接开个数组记录前缀和就好了,少一个log呢。
于是我们就,每次块内大小$>sz$或者最小值最大值之差$>S$,我们就新开一个块。
然后每隔一段时间重新分一下块,这样就非常优秀啦。
一开始自己智障,把$S$设得有点大,T掉了。
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<set>
using namespace std;
#define ll long long
#define db double
#define For(i,a,b) for(register int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(register int i=(a);i>=(b);--i)
const int maxn=2e5+7,maxt=1000+7,maxs=2e4+7,S=2e3,INF=0x3f3f3f3f;
int n,m,len,a[maxn],bel[maxn],sz;
int L[maxn],R[maxn]; char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;cc=getchar();ff=1;
while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
if(cc=='-') ff=-1,cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
aa*=ff;
} int fir[maxn],nxt[maxn],to[maxn],e=0,v[maxn];
void add(int x,int y,int z) {
to[++e]=y;nxt[e]=fir[x];fir[x]=e;v[e]=z;
} int dfn[maxn],fed[maxn],dfn_clock;
void dfs(int pos,int d) {
dfn[pos]=++dfn_clock;
a[dfn_clock]=d;
for(int y=fir[pos];y;y=nxt[y]) dfs(to[y],d+v[y]);
fed[pos]=dfn_clock;
} int sum[maxt][maxs],pl[maxt],pr[maxt],tot;
int d[maxn]; inline void pd(int x) {
if(!d[x]) return;
For(i,L[x],R[x]) a[i]+=d[x];
d[x]=0;
} inline void ud(int x) {
pl[x]=INF; pr[x]=-INF;
For(j,L[x],R[x]) {
pl[x]=min(pl[x],a[j]);
pr[x]=max(pr[x],a[j]);
}
For(j,0,pr[x]-pl[x]) sum[x][j]=0;
For(j,L[x],R[x]) ++sum[x][a[j]-pl[x]];
For(j,1,pr[x]-pl[x]) sum[x][j]+=sum[x][j-1];
} void bld() {
For(i,1,tot) pd(i);
int now=1,ld=INF,rd=-INF; L[1]=1;
For(i,1,n) {
ld=min(ld,a[i]); rd=max(rd,a[i]);
if(rd-ld>S||i-L[now]>=sz) {
R[now]=i-1;
L[++now]=i;
ld=rd=a[i];
}
R[bel[i]=now]=i;
}
tot=now;
For(i,1,tot) ud(i);
} inline int get_sum(int p,int x) {
if(x<pl[p]) return 0;
if(x>pr[p]) return sum[p][pr[p]-pl[p]];
return sum[p][x-pl[p]];
} inline int q(int ld,int rd,int x) {
int rs=0,lt=bel[ld],rt=bel[rd];
if(lt==rt) {
For(i,ld,rd) if(a[i]<=x) ++rs;
return rs;
}
if(ld!=L[lt]) {For(i,ld,R[lt]) if(a[i]<=x) ++rs;}
else rs+=get_sum(lt,x);
if(rd!=R[rt]) {For(i,L[rt],rd) if(a[i]<=x) ++rs;}
else rs+=get_sum(rt,x);
For(i,lt+1,rt-1) rs+=get_sum(i,x);
return rs;
} inline int Yth(int ld,int rd,int k) {
int lt=bel[ld],rt=bel[rd];
pd(lt); pd(rt);
if(rd-ld+1<k) return -1;
int l=INF,r=-INF,mid;
For(i,lt,rt) l=min(l,pl[i]),r=max(r,pr[i]);
if(l==r) return l; --l;
while(l<r-1) {
mid=(l+r)>>1;
if(q(ld,rd,mid)>=k) r=mid;
else l=mid;
}
return r;
} inline void chge(int ld,int rd,int x) {
int lt=bel[ld],rt=bel[rd];
if(lt==rt) {
pd(lt); For(i,ld,rd) a[i]+=x; ud(lt);
return;
}
if(ld!=L[lt]) {
pd(lt); For(i,ld,R[lt]) a[i]+=x; ud(lt);
}
else d[lt]+=x,pl[lt]+=x,pr[lt]+=x;
if(rd!=R[rt]) {
pd(rt); For(i,L[rt],rd) a[i]+=x; ud(rt);
}
else d[rt]+=x,pl[rt]+=x,pr[rt]+=x;
For(i,lt+1,rt-1) d[i]+=x,pl[i]+=x,pr[i]+=x;
} int main() {
read(n); read(m); read(len); sz=300;
int op,x,y;
For(i,2,n) {
read(x); read(y);
add(x,i,y);
}
dfs(1,0);
bld();
For(i,1,m) {
read(op); read(x); read(y);
if(op==1) printf("%d\n",Yth(dfn[x],fed[x],y));
else chge(dfn[x],fed[x],y);
if(i%1000==0) bld();
}
return 0;
}
loj6046 「雅礼集训 2017 Day8」爷的更多相关文章
- loj #6046. 「雅礼集训 2017 Day8」爷
#6046. 「雅礼集训 2017 Day8」爷 题目描述 如果你对山口丁和 G&P 没有兴趣,可以无视题目背景,因为你估计看不懂 …… 在第 63 回战车道全国高中生大赛中,军神西住美穗带领 ...
- LOJ#6046. 「雅礼集训 2017 Day8」爷(分块)
题面 传送门 题解 转化为\(dfs\)序之后就变成一个区间加,区间查询\(k\)小值的问题了,这显然只能分块了 然而我们分块之后需要在块内排序,然后二分\(k\)小值并在块内二分小于它的元素--一个 ...
- LOJ_6045_「雅礼集训 2017 Day8」价 _最小割
LOJ_6045_「雅礼集训 2017 Day8」价 _最小割 描述: 有$n$种减肥药,$n$种药材,每种减肥药有一些对应的药材和一个收益. 假设选择吃下$K$种减肥药,那么需要这$K$种减肥药包含 ...
- 【LYOI 212】「雅礼集训 2017 Day8」价(二分匹配+最大权闭合子图)
「雅礼集训 2017 Day8」价 内存限制: 512 MiB时间限制: 1000 ms 输入文件: z.in输出文件: z.out [分析] 蛤?一开始看错题了,但是也没有改,因为不会做. 一开 ...
- loj6045 「雅礼集训 2017 Day8」价
我们考虑最小割. 我一开始觉得是裸的最小割,就直接S到每个减肥药连up+p[i]的边,减肥药到药材连inf边,药材到T连up,然后得到了40分的好成绩. 之后我发现这是一个假的最小割,最小割割的是代价 ...
- [LOJ#6044]. 「雅礼集训 2017 Day8」共[二分图、prufer序列]
题意 题目链接 分析 钦定 \(k\) 个点作为深度为奇数的点,有 \(\binom{n-1}{k-1}\) 种方案. 将树黑白染色,这张完全二分图的生成树的个数就是我们钦定 \(k\) 个点之后合法 ...
- LOJ#6045. 「雅礼集训 2017 Day8」价(最小割)
题面 传送门 题解 首先先把所有权值取个相反数来求最大收益,因为最小收益很奇怪 然后建图如下:\(S\to\)药,容量\(\inf+p_i\),药\(\to\)药材,容量\(\inf\),药材\(\t ...
- LOJ#6044. 「雅礼集训 2017 Day8」共(Prufer序列)
题面 传送门 题解 答案就是\(S(n-k,k)\times {n-1\choose k-1}\) 其中\(S(n,m)\)表示左边\(n\)个点,右边\(m\)个点的完全二分图的生成树个数,它的值为 ...
- 【LOJ6045】「雅礼集训 2017 Day8」价(网络流)
点此看题面 大致题意: 有\(n\)种药,每种药有一个权值,且使用了若干种药材.让你选择若干种药,使得药的数量与所使用的药材并集大小相等,求最小权值总和. 网络流 \(hl666\):这种数据范围,一 ...
随机推荐
- 【珍惜时间】iReport
项目很点意思,感觉很高超的样子 先放下项目的github地址:https://github.com/tctangyanan/iReport 感谢各位伟大的程序员无私的分享自己的技术 老规矩,我们会运行 ...
- Android开发 SpannableString开发详解
前言 SpannableString,是google提供用来处理富文本的功能类.支持很多文本内容的效果变化.另外,它也是Android实现富文本编辑器的关键. 关键API详解 String conte ...
- P4860 Roy&October之取石子II
4的倍数不行,之间的数都可以到4的倍数,而6的倍数不能到4的倍数 #include <iostream> #include <cstdio> #include <queu ...
- 基础回顾: 关于Session的一些细节
1 session是服务端技术, cookie是客户端技术 2 默认情况下, 一个浏览器独占一个session对象, 也就是说, 开启两个浏览器进程, 它们之间使用的session不是同一个sessi ...
- 【五校联考5day1】登山
题目 描述 题目大意 给你一个n∗nn*nn∗n的网格图.从(0,0)(0,0)(0,0)开始,每次只可以向右或向上移动一格,并且不能越过对角线(即不能为x<yx<yx<y). 网格 ...
- ST(RMQ)算法(在线)求LCA
在此之前,我写过另一篇博客,是倍增(在线)求LCA.有兴趣的同学可以去看一看.概念以及各种暴力就不在这里说了,那篇博客已经有介绍了. 不会ST算法的同学点这里 ST(RMQ)算法在线求LCA 这个算法 ...
- 阿里重磅开源首款自研科学计算引擎Mars,揭秘超大规模科学计算
日前,阿里巴巴正式对外发布了分布式科学计算引擎 Mars 的开源代码地址,开发者们可以在pypi上自主下载安装,或在Github上获取源代码并参与开发. 此前,早在2018年9月的杭州云栖大会上,阿里 ...
- 前端CSS样式操作
目录 字体和文字 设置标签的宽高 字体属性 文字的属性 文字对齐 text-align 文字装饰 text-decoration 首行缩进 text-indent 背景属性 背景图片 边框 画圆 di ...
- 12DUILib经典教程(实例)
Duilib经典实例教程:1基本框架:一个简单的Duilib程序一般是下面这个样子的:://Duilib使用设置部分:#pragmaonce:#defineWIN32_LEAN_AND_ME:#def ...
- fiddler报错:creation of the root certificate was not successful 证书安装不成功
fiddler提示:creation of the root certificate was not successful 证书安装不成功 首先 找到Tools——>Options 在弹出的菜单 ...