luogu3242 接水果 (整体二分+树状数组)
考虑整体二分,问题就变成了每个(水果)路径有多少个满足条件(权值)的(盘子)子路径
考虑一个盘子(a,b)表示两端点(不妨设dfn[a]<dfn[b]),那么他能接到的水果(u,v)一定满足(不妨设dfn[u]<dfn[v]):
1.如果a是b的祖先,则u在(a的在(b,a)链上的孩子)这个子树外,v在b子树内
2.否则,u在a的子树内,v在b的子树内
那么把一个水果(a,b)看成是一个二维点(dfn[a],dfn[b]),对于每个盘子,就是做一个二维区间+1
差分以后变成一个二维数点问题,可以先按x排序,y用树状数组来解决
复杂度$O(nlog^2n)$
然而我写的常数过大哪都卡不过去
#include<bits/stdc++.h>
#define CLR(a,x) memset(a,x,sizeof(a))
#define MP make_pair
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pa;
const int maxn=4e4+,maxp=1e7+; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int N,P,Q;
int eg[maxn*][],egh[maxn],ect;
int dfn[maxn][],tot;
int rt[maxn],fa[maxn][],dep[maxn];
int tr[maxn]; inline int lowbit(int x){return x&(-x);} inline void add(int x,int d){
for(;x&&x<=N;x+=lowbit(x)) tr[x]+=d;
}
inline int query(int x){
int re=;
for(;x;x-=lowbit(x)) re+=tr[x];
return re;
} inline void adeg(int a,int b){
eg[++ect][]=b,eg[ect][]=egh[a],egh[a]=ect;
} inline void dfs(int x){
for(int i=;fa[x][i]&&fa[fa[x][i]][i];i++){
fa[x][i+]=fa[fa[x][i]][i];
}
dfn[x][]=++tot;
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==fa[x][]) continue;
fa[b][]=x,dep[b]=dep[x]+;
dfs(b);
}dfn[x][]=tot;
} inline int jump(int x,int d){
for(int i=;d;i++,d>>=){
if(d&) x=fa[x][i];
}return x;
} int ans[maxn],nct;
pa val[maxn];
struct Node{
int a,b,d,v,i;
}op[maxn*],tmp[maxn*]; inline void addnode(int x1,int x2,int y1,int y2,int v,int i){
op[++nct]=(Node){x1,y1,,v,i};
if(x2<N&&y2<N) op[++nct]=(Node){x2+,y2+,,v,i};
if(x2<N) op[++nct]=(Node){x2+,y1,-,v,i};
if(y2<N) op[++nct]=(Node){x1,y2+,-,v,i};
} inline void cover(int a,int b,int v,int i){
if(dfn[a][]>dfn[b][]) swap(a,b);
if(dfn[a][]>=dfn[b][]){
int x=jump(b,dep[b]-dep[a]-);
addnode(,dfn[x][]-,dfn[b][],dfn[b][],v,i);
addnode(dfn[b][],dfn[b][],dfn[x][]+,N,v,i);
}else{
addnode(dfn[a][],dfn[a][],dfn[b][],dfn[b][],v,i);
}
} inline void solve(int l,int r,int ql,int qr){
if(l>r||ql>qr) return;
int m=ql+qr>>;
// printf("~%d %d %d %d %d\n",l,r,ql,qr,val[m]);
int p=l-,q=r+;
for(int i=l;i<=r;i++){
if(op[i].d){
if(MP(op[i].v,op[i].i)<=val[m]){
add(op[i].b,op[i].d);
tmp[++p]=op[i];
}else tmp[--q]=op[i];
}else{
int n=query(op[i].b);
if(n>=op[i].v){
ans[op[i].i]=val[m].first;
tmp[++p]=op[i];
}else if(n<op[i].v){
op[i].v-=n;
tmp[--q]=op[i];
}
} }
for(int i=l;i<=r;i++){
if(op[i].d){
if(MP(op[i].v,op[i].i)<=val[m]){
add(op[i].b,-op[i].d);
}
}
}
for(int i=l;i<=p;i++) op[i]=tmp[i];
for(int i=q;i<=r;i++) op[r-i+q]=tmp[i];
solve(l,p,ql,m-),solve(q,r,m+,qr);
} inline bool cmp(Node a,Node b){return a.a==b.a?a.d!=:a.a<b.a;} int main(){
// freopen("fruit1.in","r",stdin);
// freopen("aa.out","w",stdout);
int i,j,k;
N=rd(),P=rd(),Q=rd();
for(i=;i<N;i++){
int a=rd(),b=rd();
adeg(a,b);adeg(b,a);
}
dep[]=;dfs();
for(i=;i<=P;i++){
int a=rd(),b=rd(),c=rd();
val[i]=MP(c,i);
cover(a,b,c,i);
}sort(val+,val+P+);
for(i=;i<=Q;i++){
int a=rd(),b=rd(),c=rd();
if(dfn[a][]>dfn[b][]) swap(a,b);
op[++nct]=(Node){dfn[a][],dfn[b][],,c,i};
}
sort(op+,op+nct+,cmp);
solve(,nct,,P);
for(i=;i<=Q;i++) printf("%d\n",ans[i]);
return ;
}
luogu3242 接水果 (整体二分+树状数组)的更多相关文章
- 【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组
题目描述 给出一棵n个点的树,给定m条路径,每条路径有一个权值.q次询问求一个路径包含的所有给定路径中权值第k小的. 输入 第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数. 接下来n ...
- 【BZOJ-2527】Meteors 整体二分 + 树状数组
2527: [Poi2011]Meteors Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 831 Solved: 306[Submit][Stat ...
- 【BZOJ3110】【整体二分+树状数组区间修改/线段树】K大数查询
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...
- BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组
BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位 ...
- 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...
- 【bzoj2527】[Poi2011]Meteors 整体二分+树状数组
题目描述 有N个成员国.现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站. 这个星球经常会下陨石雨.BIU已经预测了接下来K场陨石雨的情况.BI ...
- [bzoj1901][zoj2112][Dynamic Rankings] (整体二分+树状数组 or 动态开点线段树 or 主席树)
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
- 【ZOJ2112】【整体二分+树状数组】带修改区间第k大
The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...
- BZOJ2527[Poi2011]Meteors——整体二分+树状数组
题目描述 Byteotian Interstellar Union (BIU) has recently discovered a new planet in a nearby galaxy. The ...
随机推荐
- tomcat7 server.xml max thread
java - Tomcat - maxThreads vs maxConnections - Stack Overflowhttps://stackoverflow.com/questions/246 ...
- [编程笔记]第二章 C语言预备知识
/*第二讲 C语言预备专业知识 1.CPU 内存条 硬盘 显卡 主板 显示器之间的关系 CPU不能直接处理硬盘上的数据 文件存储在硬盘,当运行时,操作系统把硬盘上的数据调用到内存条上. 图像以数据的形 ...
- java中的定时任务小示例
package package_1; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Timer; ...
- [FreeBuff]Trojan.Miner.gbq挖矿病毒分析报告
Trojan.Miner.gbq挖矿病毒分析报告 https://www.freebuf.com/articles/network/196594.html 竟然还有端口转发... 这哥们.. 江民安全 ...
- docker学习笔记二
知识点: 1)手动构建镜像 2)Dockerfile快速构建镜像 阿里云yum源https://opsx.alibaba.com/mirror 镜像制作nginx镜像实例 创建并运行centos容器 ...
- docker 列出每个容器的IP
抄来的...找不到出处了. 常用方法有两种 docker inspect 容器ID | grep IPAddress 方法二 查看docker name: sudo docker inspect ...
- 解决spring多线程不共享事务的问题
在一个事务中使用多线程操作数据库时,若同时存在对数据库的读写操作,可能出现数据读取的不准确,因为多线程将不会共享同一个事务(也就是说子线程和主线程的事务不一样),为了解决这个问题,可以使用spring ...
- DotNetty 实现 Modbus TCP 系列 (四) Client & Server
本文已收录至:开源 DotNetty 实现的 Modbus TCP/IP 协议 Client public class ModbusClient { public string Ip { get; } ...
- JarvisOJ Basic Base64?
GUYDIMZVGQ2DMN3CGRQTONJXGM3TINLGG42DGMZXGM3TINLGGY4DGNBXGYZTGNLGGY3DGNBWMU3WI=== 题目非常具有迷惑性,我一开始以为就是一 ...
- POJ 2299 -Ultra-QuickSort-树状数组求逆序数
POJ 2299Ultra-QuickSort 使用树状数组记录逆序对数. 把数组按照大小顺序插入,getsum(i)就是i前面的比他大的数. #include <cstdio> #inc ...