zoukankan      html  css  js  c++  java
  • BZOJ3307: 雨天的尾巴

    3307: 雨天的尾巴

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 130  Solved: 65
    [Submit][Status]

    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


    5 3
    1 2
    3 1
    3 4
    5 4
    2 3 3
    1 5 2
    3 3 3

    Sample Output

    2
    3
    3
    0
    2


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

    HINT

    Source

    题目:

    最近老是逗逼。。。

    考虑在如果是序列上的情况,那么我们直接加是不行的,我们类似于差分,可以在x上标记一个z+1的标志,在y上标记一个z-1的标志,最后把数列从头扫一遍,用一个线段树查询最大值即可。

    现在在树上,我们只要树链剖分了之后做标记,最后扫描每条重链即可。

    代码:

      1 #include<cstdio>
      2 
      3 #include<cstdlib>
      4 
      5 #include<cmath>
      6 
      7 #include<cstring>
      8 
      9 #include<algorithm>
     10 
     11 #include<iostream>
     12 
     13 #include<vector>
     14 
     15 #include<map>
     16 
     17 #include<set>
     18 
     19 #include<queue>
     20 
     21 #include<string>
     22 
     23 #define inf 1000000000
     24 
     25 #define maxn 250000+5
     26 
     27 #define maxm 2500000+5
     28 
     29 #define eps 1e-10
     30 
     31 #define ll long long
     32 
     33 #define pa pair<int,int>
     34 
     35 #define for0(i,n) for(int i=0;i<=(n);i++)
     36 
     37 #define for1(i,n) for(int i=1;i<=(n);i++)
     38 
     39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
     40 
     41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
     42 
     43 #define mod 1000000007
     44 
     45 using namespace std;
     46 
     47 inline int read()
     48 
     49 {
     50 
     51     int x=0,f=1;char ch=getchar();
     52 
     53     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     54 
     55     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
     56 
     57     return x*f;
     58 
     59 }
     60 int n,m,q,tot[2],head[maxn][2],top[maxn],id[maxn],son[maxn],dep[maxn],s[maxn],fa[maxn],ans[maxn];
     61 int a[maxn];
     62 struct edge{int go,next,ch;}e[maxm][2];
     63 struct seg{int l,r,mx[2];}t[4*maxn];
     64 map<int,int>mp;
     65 inline void ins(int k,int x,int y,int z)
     66 {
     67     e[++tot[k]][k]=(edge){y,head[x][k],z};head[x][k]=tot[k];
     68 }
     69 inline void insert(int k,int x,int y,int z)
     70 {
     71     ins(k,x,y,z);ins(k,y,x,z);
     72 }
     73 inline void dfs(int x)
     74 {
     75     s[x]=1;
     76     for(int i=head[x][0],y;i;i=e[i][0].next)
     77         if(!dep[y=e[i][0].go])
     78         {
     79             dep[y]=dep[x]+1;fa[y]=x;
     80             dfs(y);
     81             s[x]+=s[y];
     82             if(s[y]>s[son[x]])son[x]=y;
     83         }
     84 }
     85 inline void dfs2(int x,int chain)
     86 {
     87     id[x]=++m;top[x]=chain;
     88     if(son[x])dfs2(son[x],chain);
     89     for(int i=head[x][0];i;i=e[i][0].next)if(e[i][0].go!=son[x]&&e[i][0].go!=fa[x])dfs2(e[i][0].go,e[i][0].go);
     90 }
     91 inline void pushup(int k)
     92 {
     93     int l=k<<1,r=k<<1|1;
     94     t[k].mx[0]=-1;
     95     if(t[l].mx[0]>t[k].mx[0]||(t[l].mx[0]==t[k].mx[0]&&a[t[l].mx[1]]<a[t[k].mx[1]]))t[k].mx[0]=t[l].mx[0],t[k].mx[1]=t[l].mx[1];
     96     if(t[r].mx[0]>t[k].mx[0]||(t[r].mx[0]==t[k].mx[0]&&a[t[r].mx[1]]<a[t[k].mx[1]]))t[k].mx[0]=t[r].mx[0],t[k].mx[1]=t[r].mx[1];
     97 }
     98 inline void build(int k,int l,int r)
     99 {
    100     t[k].l=l;t[k].r=r;int mid=(l+r)>>1;
    101     if(l==r){t[k].mx[0]=0;t[k].mx[1]=l;return;}
    102     build(k<<1,l,mid);build(k<<1|1,mid+1,r);
    103 }
    104 inline void add(int k,int x,int y)
    105 {
    106     int l=t[k].l,r=t[k].r,mid=(l+r)>>1;
    107     if(l==r){t[k].mx[0]+=y;return;}
    108     if(x<=mid)add(k<<1,x,y);else add(k<<1|1,x,y);
    109     pushup(k);
    110 }
    111 inline void dfs3(int x)
    112 {
    113     for(int i=head[x][1];i;i=e[i][1].next)
    114         if(e[i][1].ch==1)add(1,e[i][1].go,1);
    115     ans[x]=t[1].mx[0]?t[1].mx[1]:0;
    116     for(int i=head[x][1];i;i=e[i][1].next)
    117         if(e[i][1].ch==-1)add(1,e[i][1].go,-1);
    118     if(son[x])dfs3(son[x]);
    119 }
    120 
    121 int main()
    122 
    123 {
    124 
    125     freopen("input.txt","r",stdin);
    126 
    127     freopen("output.txt","w",stdout);
    128 
    129     n=read();q=read();
    130     for1(i,n-1)insert(0,read(),read(),0);
    131     dep[1]=1;dfs(1);dfs2(1,1);
    132     int cnt=0;
    133     for1(i,q)
    134     {
    135         int x=read(),y=read(),z=read(),t=mp[z];
    136         if(t)z=t;else mp[z]=++cnt,a[cnt]=z,z=cnt;
    137         while(top[x]!=top[y])
    138         {
    139             if(dep[top[x]]<dep[top[y]])swap(x,y);
    140             ins(1,top[x],z,1);
    141             ins(1,x,z,-1);
    142             x=fa[top[x]];
    143         }
    144         if(dep[x]>dep[y])swap(x,y);
    145         ins(1,x,z,1);
    146         ins(1,y,z,-1);
    147     }
    148     build(1,1,cnt);
    149     for1(i,n)if(top[i]==i)dfs3(i);
    150     for1(i,n)printf("%d
    ",a[ans[i]]);
    151 
    152     return 0;
    153 
    154 }  
    View Code

    无解的情况WA了好久。。。结果对拍了一组数据就看出问题了。。。

  • 相关阅读:
    10 个雷人的注释,就怕你不敢用!
    Java 14 之模式匹配,非常赞的一个新特性!
    poj 3661 Running(区间dp)
    LightOJ
    hdu 5540 Secrete Master Plan(水)
    hdu 5584 LCM Walk(数学推导公式,规律)
    hdu 5583 Kingdom of Black and White(模拟,技巧)
    hdu 5578 Friendship of Frog(multiset的应用)
    hdu 5586 Sum(dp+技巧)
    hdu 5585 Numbers
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4142589.html
Copyright © 2011-2022 走看看