[整体二分 || 树套树 || 点分治] BZOJ 4009 [HNOI2015]接水果
来源:互联网 发布:淘宝哪家情侣装好看 编辑:程序博客网 时间:2024/05/21 18:40
整体二分的做法题解很多:http://blog.csdn.net/thy_asdf/article/details/50363672
点分治么 还不会233
树套树么 ORZ
打的整体二分
#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;inline char nc(){static char buf[100000],*p1=buf,*p2=buf;if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }return *p1++;}inline void read(int &x){char c=nc(),b=1;for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}const int N=100005;namespace TREE{#define V G[p].vstruct edge{int u,v,next;};edge G[N<<1];int head[N],inum;inline void add(int u,int v,int p){G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;}int clk;int size[N],pre[N],last[N],fat[N][21],depth[N];inline void dfs(int u,int fa){size[u]=1; pre[u]=++clk; depth[u]=depth[fa]+1; fat[u][0]=fa;for (int k=1;k<=20;k++) fat[u][k]=fat[fat[u][k-1]][k-1]; for (int p=head[u];p;p=G[p].next)if (V!=fa)dfs(V,u),size[u]+=size[V];last[u]=pre[u]+size[u]-1;}inline int LCA(int u,int v){ if (depth[u]<depth[v]) swap(u,v); for (int k=20;~k;k--) if ((depth[u]-depth[v])&(1<<k)) u=fat[u][k]; if (u==v) return u; for (int k=20;~k;k--) if (fat[u][k]!=fat[v][k]) u=fat[u][k],v=fat[v][k]; return fat[u][0]; }inline int SecLCA(int x,int y){ for (int k=20;~k;k--) if (depth[fat[x][k]]>depth[y]) x=fat[x][k]; return x; }}int n,P,Q;int ans[N];struct Query{int x,y,k;int idx;}que[N],tmp[N];int qtot;struct Matrix{int x1,x2,y1,y2,key;bool operator < (const Matrix &B) const{return key<B.key;}}mat[N<<1];int mtot;namespace BIT{#define lowbit(x) ((x)&-(x))int c[N];inline void add(int x,int t){for (int i=x;i<=n;i+=lowbit(i))c[i]+=t;}inline void add(int l,int r,int t){add(l,t); add(r+1,-t);}inline int query(int x){int ret=0;for (int i=x;i;i-=lowbit(i))ret+=c[i];return ret;}}struct event{int x,y1,y2,r;event() { }event(int x,int y1,int y2,int r):x(x),y1(y1),y2(y2),r(r) { }bool operator < (const event &B) const{return x==B.x?(r>B.r):(x<B.x);}}eve[N<<2];int tot;int cnt[N<<2];inline void Solve(int l,int r,int ql,int qr){if (l==r){for (int i=ql;i<=qr;i++) ans[que[i].idx]=mat[l].key;return;}int mid=(l+r)>>1;tot=0;for (int i=l;i<=mid;i++) eve[++tot]=event(mat[i].x1,mat[i].y1,mat[i].y2,1),eve[++tot]=event(mat[i].x2,mat[i].y1,mat[i].y2,-1);for (int i=ql;i<=qr;i++) eve[++tot]=event(que[i].x,que[i].y,i,0);sort(eve+1,eve+tot+1);for (int i=1;i<=tot;i++)if (eve[i].r==1)BIT::add(eve[i].y1,eve[i].y2,1);else if (eve[i].r==-1)BIT::add(eve[i].y1,eve[i].y2,-1);else if (eve[i].r==0)cnt[eve[i].y2]=BIT::query(eve[i].y1);int L=ql-1,R=qr+1;for (int i=ql;i<=qr;i++)if (cnt[i]<que[i].k)tmp[--R]=que[i],tmp[R].k-=cnt[i];elsetmp[++L]=que[i];for (int i=ql;i<=qr;i++)que[i]=tmp[i];if (ql<=L) Solve(l,mid,ql,L);if (R<=qr) Solve(mid+1,r,R,qr);}int main(){using namespace TREE;int iu,iv,ik,w,lca;freopen("t.in","r",stdin);freopen("t.out","w",stdout);read(n); read(P); read(Q);for (int i=1;i<n;i++)read(iu),read(iv),add(iu,iv,++inum),add(iv,iu,++inum);dfs(1,0);for (int i=1;i<=P;i++){read(iu); read(iv); read(ik);if (pre[iu]>pre[iv]) swap(iu,iv);if ((lca=LCA(iu,iv))==iu){w=SecLCA(iv,iu);if (pre[w]-1>0){mat[++mtot].key=ik;mat[mtot].x1=1; mat[mtot].x2=pre[w]-1; mat[mtot].y1=pre[iv]; mat[mtot].y2=last[iv];}if (last[w]+1<=n){mat[++mtot].key=ik;mat[mtot].x1=pre[iv]; mat[mtot].x2=last[iv]; mat[mtot].y1=last[w]+1; mat[mtot].y2=n; }}else{mat[++mtot].key=ik;mat[mtot].x1=pre[iu]; mat[mtot].x2=last[iu]; mat[mtot].y1=pre[iv]; mat[mtot].y2=last[iv];}}sort(mat+1,mat+mtot+1);for (int i=1;i<=Q;i++){read(iu); read(iv); read(ik);if (pre[iu]>pre[iv]) swap(iu,iv);que[++qtot].k=ik; que[qtot].x=pre[iu]; que[qtot].y=pre[iv]; que[qtot].idx=i;}Solve(1,mtot,1,qtot);for (int i=1;i<=Q;i++) printf("%d\n",ans[i]);return 0;}
0 0
- [整体二分 || 树套树 || 点分治] BZOJ 4009 [HNOI2015]接水果
- BZOJ 4009 HNOI2015 接水果 树套树
- bzoj 4009 [HNOI2015]接水果 树套树
- 4009: [HNOI2015]接水果
- BZOJ 4012 HNOI2015 开店 动态树分治+二分
- bzoj4009: [HNOI2015]接水果
- bzoj4009 [HNOI2015]接水果
- 【BZOJ4009】[HNOI2015]接水果
- BZOJ4009 HNOI2015 接水果
- BZOJ4009 HNOI2015 接水果
- BZOJ4009: [HNOI2015]接水果 kdtree
- CDQ分治&&整体二分
- 【动态树分治】【bzoj 4012】: [HNOI2015]开店
- BZOJ 4012: [HNOI2015]开店 -- 动态树分治
- BZOJ4009: [HNOI2015]接水果 解题报告
- bzoj 3219: 巡游 (点分治+单调队列+二分)
- [总结]CDQ分治&整体二分
- 整体二分<QAQ> && CDQ分治
- 【BZOJ4597】【Shoi2016】随机序列 线段树
- redis简介
- 343. Integer Break
- [leetcode] 239. Sliding Window Maximum
- Box2d源码学习<十二>b2Collision之碰撞(上)公共部分的实现
- [整体二分 || 树套树 || 点分治] BZOJ 4009 [HNOI2015]接水果
- 欢迎使用CSDN-markdown编辑器
- redis常见的五种数据类型
- 欢迎使用CSDN-markdown编辑器
- Android常用控件
- Android防止事件重复提交
- 关于linux启动
- 杭电 2053(循环)
- Python项目中基础知识回顾之路(2)