zoukankan      html  css  js  c++  java
  • 【BZOJ 3307】 3307: 雨天的尾巴 (线段树+树链剖分)

    3307: 雨天的尾巴

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 458  Solved: 210

    Description

    N个点,形成一个树状结构。有M次发放,每次选择两个点x,y
    对于x到y的路径上(含x,y)每个点发一袋Z类型的物品。完成
    所有发放后,每个点存放最多的是哪种物品。

    Input

    第一行数字N,M
    接下来N-1行,每行两个数字a,b,表示a与b间有一条边
    再接下来M行,每行三个数字x,y,z.如题

    Output

    输出有N行
    每i行的数字表示第i个点存放最多的物品是哪一种,如果有
    多种物品的数量一样,输出编号最小的。如果某个点没有物品
    则输出0

    Sample Input

    20 50
    8 6
    10 6
    18 6
    20 10
    7 20
    2 18
    19 8
    1 6
    14 20
    16 10
    13 19
    3 14
    17 18
    11 19
    4 11
    15 14
    5 18
    9 10
    12 15
    11 14 87
    12 1 87
    14 3 84
    17 2 36
    6 5 93
    17 6 87
    10 14 93
    5 16 78
    6 15 93
    15 5 16
    11 8 50
    17 19 50
    5 4 87
    15 20 78
    1 17 50
    20 13 87
    7 15 22
    16 11 94
    19 8 87
    18 3 93
    13 13 87
    2 1 87
    2 6 22
    5 20 84
    10 12 93
    18 12 87
    16 10 93
    8 17 93
    14 7 36
    7 4 22
    5 9 87
    13 10 16
    20 11 50
    9 16 84
    10 17 16
    19 6 87
    12 2 36
    20 9 94
    9 2 84
    14 1 94
    5 5 94
    8 17 16
    12 8 36
    20 17 78
    12 18 50
    16 8 94
    2 19 36
    10 18 36
    14 19 50
    4 12 50

    Sample Output

    87
    36
    84
    22
    87
    87
    22
    50
    84
    87
    50
    36
    87
    93
    36
    94
    16
    87
    50
    50



    1<=N,M<=100000
    1<=a,b,x,y<=N
    1<=z<=10^9

    HINT

    Source

    【分析】

      什么时候样例这样良心。。

      按照z排序,然后树剖标记一下区间,然后统计个数相同的区间add到线段树里面求min,这些区间个数不会超过3*mlogn,因为树剖区间logn个,一个新的区间最多只会把原来的分割成3部分。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 using namespace std;
      7 #define Maxn 100010
      8 
      9 int mymax(int x,int y) {return x>y?x:y;}
     10 
     11 struct node
     12 {
     13     int l,r,lc,rc,mx,id;
     14     int lazy,lad;
     15 }tr[Maxn*2];
     16 
     17 struct nnode{int x,y,z;}t[Maxn],tt[Maxn],t3[Maxn*40];
     18 int first[Maxn],len;
     19 
     20 bool cmp(nnode x,nnode y) {return x.z<y.z;}
     21 bool cmp2(nnode x,nnode y) {return x.x<y.x;}
     22 
     23 void ins(int x,int y)
     24 {
     25     t[++len].x=x;t[len].y=y;
     26     t[len].z=first[x];first[x]=len;
     27 }
     28 
     29 int fa[Maxn],son[Maxn],tp[Maxn],sm[Maxn],dep[Maxn];
     30 void dfs1(int x,int ff)
     31 {
     32     dep[x]=dep[ff]+1;
     33     fa[x]=ff;sm[x]=1;son[x]=0;
     34     for(int i=first[x];i;i=t[i].z) if(t[i].y!=ff)
     35     {
     36         int y=t[i].y;
     37         dfs1(y,x);
     38         sm[x]+=sm[y];
     39         if(son[x]==0||sm[y]>sm[son[x]]) son[x]=y;
     40     }
     41 }
     42 
     43 int cnt,dfn[Maxn];
     44 void dfs2(int x,int tpp)
     45 {
     46     dfn[x]=++cnt;tp[x]=tpp;
     47     if(son[x]) dfs2(son[x],tpp);
     48     for(int i=first[x];i;i=t[i].z) if(t[i].y!=fa[x]&&t[i].y!=son[x])
     49     {
     50         int y=t[i].y;
     51         dfs2(y,y);
     52     }
     53 }
     54 
     55 int tot=0;
     56 int build(int l,int r)
     57 {
     58     int x=++tot;
     59     tr[x].l=l;tr[x].r=r;tr[x].mx=0;tr[x].lazy=0;
     60     if(l!=r)
     61     {
     62         int mid=(l+r)>>1;
     63         tr[x].lc=build(l,mid);
     64         tr[x].rc=build(mid+1,r);
     65     }
     66     else tr[x].lc=tr[x].rc=0;
     67     return x;
     68 }
     69 
     70 void upd(int x)
     71 {
     72     if(tr[x].lazy==0) return;
     73     int lc=tr[x].lc,rc=tr[x].rc;
     74     if(tr[x].lazy>tr[x].mx) tr[x].mx=tr[x].lazy,tr[x].id=tr[x].lad;
     75     if(tr[x].l==tr[x].r) {tr[x].lazy=0;return;}
     76     if(tr[x].lazy>tr[lc].lazy) tr[lc].lazy=tr[x].lazy,tr[lc].lad=tr[x].lad;
     77     if(tr[x].lazy>tr[rc].lazy) tr[rc].lazy=tr[x].lazy,tr[rc].lad=tr[x].lad;
     78     tr[x].lazy=0;
     79 }
     80 
     81 void change(int x,int l,int r,int y,int id)
     82 {
     83     if(tr[x].l==l&&tr[x].r==r)
     84     {
     85         if(y>tr[x].lazy) tr[x].lazy=y,tr[x].lad=id;
     86         upd(x);return;
     87     }
     88     upd(x);
     89     int mid=(tr[x].l+tr[x].r)>>1;
     90     if(r<=mid) change(tr[x].lc,l,r,y,id);
     91     else if(l>mid) change(tr[x].rc,l,r,y,id);
     92     else {change(tr[x].lc,l,mid,y,id);change(tr[x].rc,mid+1,r,y,id);}
     93     if(tr[tr[x].lc].mx>=tr[tr[x].rc].mx) tr[x].mx=tr[tr[x].lc].mx,tr[x].id=tr[tr[x].lc].id;
     94     else tr[x].mx=tr[tr[x].rc].mx,tr[x].id=tr[tr[x].rc].id;
     95 }
     96 
     97 int query(int x,int y)
     98 {
     99     upd(x);
    100     if(tr[x].l==tr[x].r) return tr[x].id;
    101     int mid=(tr[x].l+tr[x].r)>>1;
    102     if(y<=mid) return query(tr[x].lc,y);
    103     return query(tr[x].rc,y);
    104 }
    105 
    106 int tl;
    107 int add(int x,int y)
    108 {
    109     while(tp[x]!=tp[y])
    110     {
    111         if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
    112         t3[++tl].x=dfn[tp[x]];t3[tl].y=1;
    113         t3[++tl].x=dfn[x]+1;t3[tl].y=-1;
    114         x=fa[tp[x]];
    115     }
    116     if(dep[x]>dep[y]) swap(x,y);
    117     t3[++tl].x=dfn[x];t3[tl].y=1;
    118     t3[++tl].x=dfn[y]+1;t3[tl].y=-1;
    119 }
    120 
    121 void ffind(int st,int ed,int id)
    122 {
    123     tl=0;
    124     for(int i=st;i<=ed;i++) 
    125     {
    126         add(tt[i].x,tt[i].y);
    127     }
    128     sort(t3+1,t3+1+tl,cmp2);
    129     int nw=0;
    130     for(int i=1;i<tl;i++)
    131     {
    132         nw+=t3[i].y;
    133         if(t3[i].x!=t3[i+1].x&&nw!=0)
    134         {
    135             // printf("%d %d %d
    ",t3[i].x,t3[i+1].x-1,nw);
    136             change(1,t3[i].x,t3[i+1].x-1,nw,id);
    137         }
    138     }
    139 }
    140 
    141 int main()
    142 {
    143     int n,m;
    144     scanf("%d%d",&n,&m);
    145     len=0;
    146     memset(first,0,sizeof(first));
    147     for(int i=1;i<n;i++)
    148     {
    149         int x,y;
    150         scanf("%d%d",&x,&y);
    151         ins(x,y);ins(y,x);
    152     }
    153     dep[0]=0;dfs1(1,0);
    154     cnt=0;dfs2(1,1);
    155     for(int i=1;i<=m;i++) scanf("%d%d%d",&tt[i].x,&tt[i].y,&tt[i].z);
    156     sort(tt+1,tt+1+m,cmp);
    157     build(1,n);
    158     int st=1;
    159     for(int i=1;i<=m;i++)
    160     {
    161         if(i==m||tt[i].z!=tt[i+1].z)
    162         {
    163             ffind(st,i,tt[i].z);
    164             st=i+1;
    165         }
    166     }
    167     for(int i=1;i<=n;i++) printf("%d
    ",query(1,dfn[i]));
    168     return 0;
    169 }
    View Code

    好像Po姐有更好的方法?

    2017-03-27 16:10:51

  • 相关阅读:
    验证码处理 -- 爬虫
    Django知识点总结
    关于sql去重
    tsxt-01
    崔老师爬取top100的源码(会403)
    简单爬取网页源码
    爬取猫眼top100
    python-自动发邮件
    python-装饰器
    Python 爬虫基础Selenium库的使用
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6627250.html
Copyright © 2011-2022 走看看