zoukankan      html  css  js  c++  java
  • [bzoj3307]雨天的尾巴

    对每一个节点开一颗权值线段树维护打的标记(x+,y+,lca(x,y)-,fa[lca(x,y)]-),然后每一个节点将子树内所有节点(其实就是已经合并过的儿子)合并即可。
    (毒瘤的是这道题需要将物品离散化一下否则会爆栈,当然也可以写bfs)

     1 # pragma comment(linker, /STACK:102400000,102400000)
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 #define N 100005
     5 #define mid (l+r>>1)
     6 struct ji{
     7     int nex,to;
     8 }edge[N<<1];
     9 struct ji2{
    10     int x,y,z;
    11 }q[N];
    12 int E,n,m,x,y,z,head[N],a[N],b[N],in[N],out[N],f[N][21];
    13 int V,r[N],id[N*50],ls[N*50],rs[N*50],tr[N*50];
    14 bool cmp(ji2 x,ji2 y){
    15     return x.z<y.z;
    16 }
    17 void add(int x,int y){
    18     edge[E].nex=head[x];
    19     edge[E].to=y;
    20     head[x]=E++;
    21 }
    22 bool pd(int x,int y){
    23     return (in[x]<=in[y])&&(out[y]<=out[x]);
    24 }
    25 int lca(int x,int y){
    26     if (pd(x,y))return x;
    27     for(int i=20;i>=0;i--)
    28         if (!pd(f[x][i],y))x=f[x][i];
    29     return f[x][0];
    30 }
    31 void up(int k){
    32     tr[k]=max(tr[ls[k]],tr[rs[k]]);
    33     if (tr[k]==tr[ls[k]])id[k]=id[ls[k]];
    34     else id[k]=id[rs[k]];
    35 }
    36 void update(int &k,int l,int r,int x,int y){
    37     if (!k)k=++V;
    38     if (l==r){
    39         tr[k]+=y;
    40         id[k]=l;
    41         return;
    42     }
    43     if (x<=mid)update(ls[k],l,mid,x,y);
    44     else update(rs[k],mid+1,r,x,y);
    45     up(k);
    46 }
    47 void merge(int &k1,int k2,int l,int r){
    48     if (k1*k2==0){
    49         k1+=k2;
    50         return;
    51     }
    52     if (l==r){
    53         tr[k1]+=tr[k2];
    54         return;
    55     }
    56     merge(ls[k1],ls[k2],l,mid);
    57     merge(rs[k1],rs[k2],mid+1,r);
    58     up(k1);
    59 }
    60 void dfs(int k,int fa){
    61     in[k]=++x;
    62     a[x]=k;
    63     f[k][0]=fa;
    64     for(int i=1;i<=20;i++)f[k][i]=f[f[k][i-1]][i-1];
    65     for(int i=head[k];i!=-1;i=edge[i].nex)
    66         if (edge[i].to!=fa)dfs(edge[i].to,k);
    67     out[k]=x;
    68 }
    69 int main(){
    70     scanf("%d%d",&n,&m);
    71     memset(head,-1,sizeof(head));
    72     for(int i=1;i<n;i++){
    73         scanf("%d%d",&x,&y);
    74         add(x,y);
    75         add(y,x);
    76     }
    77     x=0;
    78     dfs(1,1);
    79     for(int i=1;i<=n;i++)r[i]=i;
    80     V=n;
    81     for(int i=1;i<=m;i++)scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].z);
    82     sort(q+1,q+m+1,cmp);
    83     for(int i=1;i<=m;i++){
    84         x=q[i].x;
    85         y=q[i].y;
    86         if (q[i-1].z<q[i].z)b[++z]=q[i].z;
    87         update(r[x],0,1e5,z,1);
    88         update(r[y],0,1e5,z,1);
    89         update(r[lca(x,y)],0,1e5,z,-1);
    90         if (lca(x,y)>1)update(r[f[lca(x,y)][0]],0,1e5,z,-1);
    91     }
    92     for(int i=n;i>1;i--)merge(r[f[a[i]][0]],r[a[i]],0,1e5);
    93     for(int i=1;i<=n;i++)printf("%d
    ",b[id[r[i]]]);
    94 }
    View Code
  • 相关阅读:
    Unity周记: 2020.09.07-09.13
    Unity周记: 2020.08.31-09.06
    CF1060F Shrinking Tree
    洛谷P6783 [Ynoi2008] rrusq
    洛谷P5644 [PKUWC2018] 猎人杀
    洛谷P1587 [NOI2016] 循环之美
    洛谷P4466 [国家集训队] 和与积
    集合幂级数杂题
    Flink基础(49):FLINK SQL(25) 内置函数(七)表值函数
    Flink基础(48):FLINK SQL(24) 内置函数(六)条件函数
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11834550.html
Copyright © 2011-2022 走看看