• 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)$

    然而我写的常数过大哪都卡不过去

      1 #include<bits/stdc++.h>
      2 #define CLR(a,x) memset(a,x,sizeof(a))
      3 #define MP make_pair
      4 using namespace std;
      5 typedef long long ll;
      6 typedef unsigned long long ull;
      7 typedef pair<int,int> pa;
      8 const int maxn=4e4+10,maxp=1e7+10;
      9 
     10 inline ll rd(){
     11     ll x=0;char c=getchar();int neg=1;
     12     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
     13     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
     14     return x*neg;
     15 }
     16 
     17 int N,P,Q;
     18 int eg[maxn*2][2],egh[maxn],ect;
     19 int dfn[maxn][2],tot;
     20 int rt[maxn],fa[maxn][20],dep[maxn];
     21 int tr[maxn];
     22 
     23 inline int lowbit(int x){return x&(-x);}
     24 
     25 inline void add(int x,int d){
     26     for(;x&&x<=N;x+=lowbit(x)) tr[x]+=d;
     27 }
     28 inline int query(int x){
     29     int re=0;
     30     for(;x;x-=lowbit(x)) re+=tr[x];
     31     return re;
     32 }
     33 
     34 inline void adeg(int a,int b){
     35     eg[++ect][0]=b,eg[ect][1]=egh[a],egh[a]=ect;
     36 }
     37 
     38 inline void dfs(int x){
     39     for(int i=0;fa[x][i]&&fa[fa[x][i]][i];i++){
     40         fa[x][i+1]=fa[fa[x][i]][i];
     41     }
     42     dfn[x][0]=++tot;
     43     for(int i=egh[x];i;i=eg[i][1]){
     44         int b=eg[i][0];if(b==fa[x][0]) continue;
     45         fa[b][0]=x,dep[b]=dep[x]+1;
     46         dfs(b);
     47     }dfn[x][1]=tot;
     48 }
     49 
     50 inline int jump(int x,int d){
     51     for(int i=0;d;i++,d>>=1){
     52         if(d&1) x=fa[x][i];
     53     }return x;
     54 }
     55 
     56 int ans[maxn],nct;
     57 pa val[maxn];
     58 struct Node{
     59     int a,b,d,v,i;
     60 }op[maxn*9],tmp[maxn*9];
     61 
     62 inline void addnode(int x1,int x2,int y1,int y2,int v,int i){
     63     op[++nct]=(Node){x1,y1,1,v,i};
     64     if(x2<N&&y2<N) op[++nct]=(Node){x2+1,y2+1,1,v,i};
     65     if(x2<N) op[++nct]=(Node){x2+1,y1,-1,v,i};
     66     if(y2<N) op[++nct]=(Node){x1,y2+1,-1,v,i};
     67 }
     68 
     69 inline void cover(int a,int b,int v,int i){
     70     if(dfn[a][0]>dfn[b][0]) swap(a,b);
     71     if(dfn[a][1]>=dfn[b][1]){
     72         int x=jump(b,dep[b]-dep[a]-1);
     73         addnode(1,dfn[x][0]-1,dfn[b][0],dfn[b][1],v,i);
     74         addnode(dfn[b][0],dfn[b][1],dfn[x][1]+1,N,v,i);
     75     }else{
     76         addnode(dfn[a][0],dfn[a][1],dfn[b][0],dfn[b][1],v,i);
     77     }
     78 }
     79 
     80 inline void solve(int l,int r,int ql,int qr){
     81     if(l>r||ql>qr) return;
     82     int m=ql+qr>>1;
     83     // printf("~%d %d %d %d %d
    ",l,r,ql,qr,val[m]);
     84     int p=l-1,q=r+1;
     85     for(int i=l;i<=r;i++){
     86         if(op[i].d){
     87             if(MP(op[i].v,op[i].i)<=val[m]){
     88                 add(op[i].b,op[i].d);
     89                 tmp[++p]=op[i];
     90             }else tmp[--q]=op[i];
     91         }else{
     92             int n=query(op[i].b);
     93             if(n>=op[i].v){
     94                 ans[op[i].i]=val[m].first;
     95                 tmp[++p]=op[i];
     96             }else if(n<op[i].v){
     97                 op[i].v-=n;
     98                 tmp[--q]=op[i];
     99             }
    100         }
    101         
    102     }
    103     for(int i=l;i<=r;i++){
    104         if(op[i].d){
    105             if(MP(op[i].v,op[i].i)<=val[m]){
    106                 add(op[i].b,-op[i].d);
    107             }
    108         }
    109     }
    110     for(int i=l;i<=p;i++) op[i]=tmp[i];
    111     for(int i=q;i<=r;i++) op[r-i+q]=tmp[i];
    112     solve(l,p,ql,m-1),solve(q,r,m+1,qr);
    113 }
    114 
    115 inline bool cmp(Node a,Node b){return a.a==b.a?a.d!=0:a.a<b.a;}
    116 
    117 int main(){
    118     // freopen("fruit1.in","r",stdin);
    119     // freopen("aa.out","w",stdout);
    120     int i,j,k;
    121     N=rd(),P=rd(),Q=rd();
    122     for(i=1;i<N;i++){
    123         int a=rd(),b=rd();
    124         adeg(a,b);adeg(b,a);
    125     }
    126     dep[1]=1;dfs(1);
    127     for(i=1;i<=P;i++){
    128         int a=rd(),b=rd(),c=rd();
    129         val[i]=MP(c,i);
    130         cover(a,b,c,i);
    131     }sort(val+1,val+P+1);
    132     for(i=1;i<=Q;i++){
    133         int a=rd(),b=rd(),c=rd();
    134         if(dfn[a][0]>dfn[b][0]) swap(a,b);
    135         op[++nct]=(Node){dfn[a][0],dfn[b][0],0,c,i};
    136     }
    137     sort(op+1,op+nct+1,cmp);
    138     solve(1,nct,1,P);
    139     for(i=1;i<=Q;i++) printf("%d
    ",ans[i]);
    140     return 0;
    141 }
  • 相关阅读:
    输出流OutputStream简单理解
    IO流实现写入规定的acci码值
    事务的ACID属性&&五种状态
    java基础总结之Hashtable
    HBase
    oracle交换分区
    ArrayList 和 LinkedList 的区别(底层数据结构): 什么时候使用arrayList,什么时候使用LinkedList (一个小时)
    Mac中MariaDB数据库的安装步骤
    Mac OS X中MacPorts安装和使用(linux 的 yum)
    SFTP秘钥认证
  • 原文地址:https://www.cnblogs.com/Ressed/p/10050585.html
Copyright © 2020-2023  润新知