• XJOI网上同步训练DAY3 T2


    考试的时候已经想出来怎么做了,但是没有时间打了T_T

    思路:我们考虑将询问以lim排序,然后树链剖分,把边作为线段树的节点,然后随着询问lim的增大,改变线段树中节点的信息,然后每次询问我们用树链剖分询问,复杂度是O(nlogn),又get一种新的树链剖分打法

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<cstring>
      6 struct node{
      7     int x,y,lim,id;
      8 }q[200005];
      9 int V[200005],dep[200005],t[200005],dfn[200005],num,n,m;
     10 struct Data{
     11     int l,r,s,v;
     12     Data(){}
     13     Data(int a,int b,int c,int d):l(a),r(b),s(c),v(d){}
     14 }s1[800005],s2[800005];
     15 Data operator +(Data a,Data b){
     16         Data ret(a.l,b.r,a.s+b.s,a.v+b.v);
     17         if (a.r&&b.l) ret.v=a.v+b.v-V[a.r]-V[b.l]+V[a.r+b.l];
     18         if (b.l==b.s) ret.r=a.r+b.s;
     19         if (a.l==a.s) ret.l=b.l+a.s;
     20         return ret;
     21 }
     22 int tot,go[200005],next[200005],first[200005];
     23 int size[200005],son[200005],top[200005],fa[200005];
     24 int ans[200005],val[200005];
     25 int read(){
     26     int t=0,f=1;char ch=getchar();
     27     while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
     28     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
     29     return t*f;
     30 }
     31 void insert(int x,int y,int z){
     32     tot++;
     33     go[tot]=y;
     34     next[tot]=first[x];
     35     first[x]=tot;
     36     val[tot]=z;
     37 }
     38 void add(int x,int y,int z){
     39     insert(x,y,z);insert(y,x,z);
     40 }
     41 bool cmp(node a,node b){
     42     return a.lim<b.lim;
     43 }
     44 bool cmp1(int x,int y){
     45     return val[x]<val[y];
     46 }
     47 void build(int k,int l,int r){
     48     if (l==r){
     49         s1[k]=s2[k]=Data(1,1,1,V[1]);
     50         return;
     51     }
     52     int mid=(l+r)/2;
     53     build(k*2,l,mid);
     54     build(k*2+1,mid+1,r);
     55     s1[k]=s1[k*2]+s1[k*2+1];
     56     s2[k]=s2[k*2+1]+s2[k*2];
     57 }
     58 void dfs1(int x,int f){
     59     size[x]=1;
     60     for (int i=first[x];i;i=next[i]){
     61         int pur=go[i];
     62         if (pur!=f){
     63             dep[pur]=dep[x]+1;
     64             t[++t[0]]=i;
     65             dfs1(pur,x);
     66             size[x]+=size[pur];
     67             if (size[pur]>size[son[x]]) son[x]=pur;
     68         }
     69     }
     70 }
     71 void dfs2(int x,int f){
     72     dfn[x]=++num;
     73     if (son[x]) top[son[x]]=top[x],dfs2(son[x],x);
     74     for (int i=first[x];i;i=next[i]){
     75         int pur=go[i];
     76         if (pur==f||pur==son[x]) continue;
     77         top[pur]=pur;
     78         fa[pur]=x;
     79         dfs2(pur,x);
     80     }
     81 }
     82 void modify(int k,int l,int r,int pos){
     83     if (l==r){
     84         s1[k]=s2[k]=Data(0,0,1,0);
     85         return;
     86     }
     87     int mid=(l+r)/2;
     88     if (pos<=mid) modify(k*2,l,mid,pos);
     89     else modify(k*2+1,mid+1,r,pos);
     90     s1[k]=s1[k*2]+s1[k*2+1];
     91     s2[k]=s2[k*2+1]+s2[k*2];
     92 }
     93 Data ask1(int k,int l,int r,int x,int y){
     94     if (l==x&&r==y){
     95         return s1[k];
     96     }
     97     int mid=(l+r)/2;
     98     if (y<=mid) return ask1(k*2,l,mid,x,y);
     99     else
    100     if (x>mid) return ask1(k*2+1,mid+1,r,x,y);
    101     else return ask1(k*2,l,mid,x,mid)+ask1(k*2+1,mid+1,r,mid+1,y);
    102 }
    103 Data ask2(int k,int l,int r,int x,int y){
    104     if (l==x&&r==y){
    105         return s2[k];
    106     }
    107     int mid=(l+r)/2;
    108     if (y<=mid) return ask2(k*2,l,mid,x,y);
    109     else
    110     if (x>mid) return ask2(k*2+1,mid+1,r,x,y);
    111     else return ask2(k*2+1,mid+1,r,mid+1,y)+ask2(k*2,l,mid,x,mid);
    112 }
    113 int work(int x,int y){
    114     Data ans1(0,0,0,0),ans2(0,0,0,0);
    115     while (top[x]!=top[y]){
    116         if (dep[top[x]]<dep[top[y]]){
    117             ans2=ask1(1,1,n,dfn[top[y]],dfn[y])+ans2;
    118             y=fa[top[y]];
    119         }else{
    120             ans1=ans1+ask2(1,1,n,dfn[top[x]],dfn[x]);
    121             x=fa[top[x]];
    122         }
    123     }
    124     if (x!=y){
    125         if (dep[x]<dep[y]){
    126             ans2=ask1(1,1,n,dfn[son[x]],dfn[y])+ans2;
    127         }else{
    128             ans1=ans1+ask2(1,1,n,dfn[son[y]],dfn[x]);
    129         }
    130     }
    131     return (ans1+ans2).v;
    132 }
    133 int main(){
    134     freopen("tx.in","r",stdin);
    135     n=read();
    136     for (int i=1;i<n;i++) V[i]=read();
    137     for (int i=1;i<n;i++){
    138         int x=read()+1,y=read()+1,v=read();
    139         add(x,y,v);
    140     }
    141     m=read();
    142     for (int i=1;i<=m;i++){
    143         q[i].x=read()+1,q[i].y=read()+1,q[i].lim=read();q[i].id=i;
    144     }
    145     dfs1(1,0);dfs2(1,0);
    146     std::sort(q+1,q+1+m,cmp);
    147     std::sort(t+1,t+1+t[0],cmp1);
    148     int h=1;build(1,1,n);
    149     for (int i=1;i<=m;i++){
    150         while (val[t[h]]<=q[i].lim&&h<=t[0]){
    151             modify(1,1,n,dfn[go[t[h]]]);
    152             h++;
    153         }
    154         ans[q[i].id]=work(q[i].x,q[i].y);
    155     }
    156     for (int i=1;i<=m;i++) printf("%d
    ",ans[i]);
    157 }
  • 相关阅读:
    java 可伸缩阻塞队列实现
    java mysql大数据量批量插入与流式读取分析
    innodb next-key lock引发的死锁
    jremoting的功能扩展点
    java开源项目jremoting
    Linux下搭建gtk+2.0开发环境
    《程序员的办公室日常》第二回 拜师
    《程序员的办公室日常》第一回 相识
    【限时免费】近1000G JAVA学习视频下载
    裁员之后,我才明白它的重要性
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5620514.html
Copyright © 2020-2023  润新知