zoukankan      html  css  js  c++  java
  • 【填坑向】spoj COT/bzoj2588 Count on a tree

    这题是学主席树的时候就想写的,,,

    但是当时没写(懒)

    现在来填坑

    = =日常调半天lca(考虑以后背板)

    主席树还是蛮好写的,但是代码出现重复,不太好,导致调试的时候心里没底(虽然事实证明主席树部分没出问题)

     1 #include <cstdio>
     2 #include <algorithm>
     3 using namespace std;
     4 struct lis{    int x,id;} li[100001];
     5 struct nod{    int num,ls,rs;} t[8000001];
     6 int n,m,x,y,z,sum=0,N=0,lastans=0;
     7 int to[200001],nex[200001],list[200001];
     8 int a[100001],h[100001],fir[100001],root[100001],f[100001],pos[100001];
     9 int log[200001],near[200001],rmq[20][200001];
    10 bool operator<(lis a,lis b){    return a.x<b.x;}
    11 void add(int x,int y,int z){    to[z]=y;nex[z]=fir[x];fir[x]=z;}
    12 inline int lca(int x,int y){    if(x>y)    swap(x,y);
    13     return (h[rmq[log[y-x+1]][x]]<h[rmq[log[y-x+1]][y-near[y-x+1]+1]])?
    14     rmq[log[y-x+1]][x]:rmq[log[y-x+1]][y-near[y-x+1]+1];}
    15 void build(int now,int fa)
    16 {
    17     f[now]=fa;root[now]=++sum;
    18     int com=root[fa],cha=root[now],l=1,r=n;
    19     while(l<r)
    20         if(a[now]>(l+r)/2)
    21             l=(l+r)/2+1,t[cha]=(nod){t[com].num+1,t[com].ls,++sum},cha=sum,com=t[com].rs;
    22         else
    23             r=(l+r)/2,t[cha]=(nod){t[com].num+1,++sum,t[com].rs},cha=sum,com=t[com].ls;
    24     list[++N]=now;pos[now]=N;t[cha]=(nod){t[com].num+1,0,0};h[now]=h[fa]+1;
    25     for(int i=fir[now];i;i=nex[i])
    26     if(to[i]!=fa)
    27         build(to[i],now),list[++N]=now;
    28 }
    29 void que(int x,int y,int z)
    30 {
    31     int l=1,r=n,lc=lca(pos[x],pos[y]),lcc=f[lc];
    32     x=root[x],y=root[y],lc=root[lc],lcc=root[lcc];
    33     while(l<r)
    34         if(t[t[x].ls].num+t[t[y].ls].num-t[t[lc].ls].num-t[t[lcc].ls].num<z)
    35             l=(l+r)/2+1,z-=t[t[x].ls].num+t[t[y].ls].num-t[t[lc].ls].num-t[t[lcc].ls].num,
    36             x=t[x].rs,y=t[y].rs,lc=t[lc].rs,lcc=t[lcc].rs;
    37         else
    38             r=(l+r)/2,x=t[x].ls,y=t[y].ls,lc=t[lc].ls,lcc=t[lcc].ls;
    39     lastans=li[l].x;
    40 }
    41 int main()
    42 {
    43     scanf("%d%d",&n,&m);
    44     for(int i=1;i<=n;i++)
    45         scanf("%d",&li[i].x),li[i].id=i;
    46     sort(li+1,li+n+1);
    47     for(int i=1;i<=n;i++)
    48         a[li[i].id]=i;
    49     for(int i=1;i<n;i++)
    50         scanf("%d%d",&x,&y),add(x,y,i),add(y,x,i+n);
    51     build(1,0);
    52     for(int i=1;i<=N;i++)
    53         rmq[0][i]=list[i];
    54     for(int i=1,j=0,k=1;i<=N;log[i]=j,near[i]=k,i++)
    55         if(i>k*2)    j++,k*=2;
    56     for(int i=1,k=2;k<=N;i++,k*=2)
    57         for(int j=1;j<=N-k+1;j++)
    58             rmq[i][j]=(h[rmq[i-1][j]]<h[rmq[i-1][j+k/2]])?rmq[i-1][j]:rmq[i-1][j+k/2];
    59     for(int i=1;i<=m;i++)
    60         scanf("%d%d%d",&x,&y,&z),que(/*lastans^*/x,y,z),printf(i<m?"%d
    ":"%d",lastans);
    61     return 0;
    62 } //lastans^加上以后就是强在,bzoj上的题;不加就是不强在,spoj上的题

    顺便吐槽:spoj上内存限制1.5G实在太6,,,

    导致我乱开数组,交bzoj的时候MLE了很多发

  • 相关阅读:
    山东财经大学新生赛暨天梯赛选拔赛 A 骆驼拼写法
    Code 墓地 问题 A: 看电视(区间贪心)
    第九届蓝桥杯 乘积尾零(Java大数)
    《真正的力量来自内心深处》
    蓝桥杯训练 历届试题 买不到的数目 (猜公式)
    前缀和与差分 算法详解
    蓝桥杯训练 历届试题 回文数字 (暴力求解,毫无任何技术含量)
    蓝桥杯训练 历届试题 最大子阵 (只用了前缀和,没用dp写)
    实习开始
    MVC缺点总结
  • 原文地址:https://www.cnblogs.com/wanglichao/p/5751685.html
Copyright © 2011-2022 走看看