• [BZOJ3307]雨天的尾巴


    雨天的尾巴

    题目描述

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

    输入格式

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

    输出格式

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

    样例

    样例输入

    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
    

    样例输出

    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<=109


     

    先说说暴力吧,这道题的暴力其实很好想,刚巧上次考试也考到了LCA和树上差分,一看题,树上差分,LCA就没跑了,看一眼数据范围的话,z直接就到了109,如果开数组一维都会炸,同时我们应该可以发现跟他相对应的m数据范围只有100000,那意思就是z最多只有100000个不同的值,离散化卡一卡说不定可以,有了这三个想法基本上也就可以打暴力了,但是由于我没有想到怎么解决二维的问题,离散化之后数组还是会炸,不炸也会MLE,所以这个思路只能拿部分分,这个暴力我估计用来打数据对拍都会崩,记得判一下题目中说的什么都没有输出0这个特殊情况就可以了(我在这死了),考试的时候想尝试结构体函数排序没成功,就直接暴力O(n)比较了,以为会超时,结果干崩了内存,这道题离散化之后内存其实也很玄妙,基本只能卡在RE和MLE之间,一不小心就MLE0了,亲身实测暴力写法最多也就50分

    正解是用权值线段树+动态开点+线段树合并,当然了LCA和差分是基础,基本上在树上需要走一个路径的话LCA和差分都可以解决,而像计算某一个值出现的次数或者是某一个区间里出现次数最多/少的点,权值线段树都没问题,这道题如果给每一个点建一颗权值线段树的话,内存依旧受不住,那动态开点就是一个很好的选择,再一个省空间的方法就是在线段树合并的时候不建新点,一直向左合并

    线段树合并其实卡了我很久,实际上就是把子节点的权值线段树不断合并到父节点的树中,合并过程中选子树的最大值记录在父节点中,再一个就是把你差分时记录的++--之类的,在当前点的完整线段树建成之后,类似于单点修改的操作,把该插入的插入,该删除的删除就行了,数组开小卡我TLE卡了大概两节课

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<vector>
      4 #include<cmath>
      5 #define maxn 100100
      6 #define ll 1
      7 #define rr 1e9
      8 #define mi 20
      9 using namespace std;
     10 struct QXX{
     11     int to,xia;
     12 }a[maxn*2];
     13 struct XDS{
     14     int cs,w,zuo,you;
     15 }b[4000100];
     16 int n,m,t,js;
     17 int head[maxn],deep[maxn],zs[maxn],ans[maxn];
     18 int fa[maxn][mi];
     19 vector <int> jia[maxn];
     20 vector <int> jian[maxn];
     21 void add(int x,int y)
     22 {
     23     a[++js].to=y;
     24     a[js].xia=head[x];
     25     head[x]=js;
     26 }
     27 void dfs(int x)
     28 {
     29     for(int i=head[x];i;i=a[i].xia)
     30     {
     31         int ls=a[i].to;
     32         if(deep[ls]==0)
     33         {
     34             deep[ls]=deep[x]+1;  fa[ls][0]=x;
     35             for(int j=1;j<=t;++j)  fa[ls][j]=fa[fa[ls][j-1]][j-1];
     36             dfs(ls);
     37         }
     38     }
     39 }
     40 int LCA(int x,int y)
     41 {
     42     if(deep[x]<deep[y])  swap(x,y);
     43     for(int i=t;i>=0;--i)
     44         if(deep[fa[x][i]]>=deep[y])  x=fa[x][i];
     45     if(x==y)  return x;
     46     for(int i=t;i>=0;--i)
     47         if(fa[x][i]!=fa[y][i])  {x=fa[x][i];  y=fa[y][i];}
     48     return fa[x][0];
     49 } 
     50 int hb(int x,int y,int l,int r)
     51 {
     52     if(x==0||y==0)  return x+y;
     53     if(l==r)  {b[x].cs+=b[y].cs;  b[x].w=l;  return x;}
     54     int mid=(l+r)/2;
     55     b[x].zuo=hb(b[x].zuo,b[y].zuo,l,mid);
     56     b[x].you=hb(b[x].you,b[y].you,mid+1,r);
     57     if(b[b[x].zuo].cs>=b[b[x].you].cs)
     58     {
     59         b[x].cs=b[b[x].zuo].cs;  b[x].w=b[b[x].zuo].w;
     60     }
     61     else  {b[x].cs=b[b[x].you].cs;  b[x].w=b[b[x].you].w;}
     62     return x;
     63 }
     64 int JIA(int d,int z,int l,int r)
     65 {
     66     if(d==0)  d=++js;
     67     if(l==r)  {b[d].cs++;  b[d].w=z;  return d;}
     68     int mid=(l+r)/2;
     69     if(z<=mid)  b[d].zuo=JIA(b[d].zuo,z,l,mid);
     70     else  b[d].you=JIA(b[d].you,z,mid+1,r);
     71     if(b[b[d].zuo].cs>=b[b[d].you].cs)
     72     {
     73         b[d].cs=b[b[d].zuo].cs;  b[d].w=b[b[d].zuo].w;
     74     }
     75     else  {b[d].cs=b[b[d].you].cs;  b[d].w=b[b[d].you].w;}
     76     return d;
     77 }
     78 int JIAN(int d,int z,int l,int r)
     79 {
     80     if(d==0)  d=++js;
     81     if(l==r)
     82     {
     83         b[d].cs--;
     84         if(b[d].cs==0)  b[d].w=0;
     85         return d;
     86     }
     87     int mid=(l+r)/2;
     88     if(z<=mid)  b[d].zuo=JIAN(b[d].zuo,z,l,mid);
     89     else  b[d].you=JIAN(b[d].you,z,mid+1,r);
     90     if(b[b[d].zuo].cs>=b[b[d].you].cs)
     91     {
     92         b[d].cs=b[b[d].zuo].cs;  b[d].w=b[b[d].zuo].w;
     93     }
     94     else  {b[d].cs=b[b[d].you].cs;  b[d].w=b[b[d].you].w;}
     95     return d;
     96 }
     97 void DFS(int x)
     98 {
     99     int zhjd=0;
    100     for(int i=head[x];i;i=a[i].xia)
    101     {
    102         int ls=a[i].to;
    103         if(fa[ls][0]==x)  {DFS(ls);  zhjd=ls;}
    104     }
    105     zs[x]=zs[zhjd];
    106     for(int i=head[x];i;i=a[i].xia)
    107     {
    108         int ls=a[i].to;
    109         if(fa[ls][0]==x&&ls!=zhjd)  zs[x]=hb(zs[x],zs[ls],ll,rr);
    110     }
    111     for(int i=0;i<jia[x].size();++i)
    112         zs[x]=JIA(zs[x],jia[x][i],ll,rr);
    113     for(int i=0;i<jian[x].size();++i)
    114         zs[x]=JIAN(zs[x],jian[x][i],ll,rr);
    115     ans[x]=b[zs[x]].w;
    116 }
    117 int main()
    118 {
    119     scanf("%d%d",&n,&m);  t=(int)(log(n)/log(2))+2;
    120     for(int i=1;i<n;++i)
    121     {
    122         int a,b;  scanf("%d%d",&a,&b);
    123         add(a,b);  add(b,a);
    124     }
    125     deep[1]=1;  dfs(1);  js=0;
    126     for(int i=1;i<=m;++i)
    127     {
    128         int o,p,q;  scanf("%d%d%d",&o,&p,&q);
    129         int z=LCA(o,p);
    130         jia[o].push_back(q);  jia[p].push_back(q);
    131         jian[z].push_back(q);  jian[fa[z][0]].push_back(q);
    132     }
    133     DFS(1);
    134     for(int i=1;i<=n;++i)  printf("%d
    ",ans[i]);
    135     return 0;
    136 }
    正解
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #define maxx 3000
     6 #define maxn 100100
     7 using namespace std;
     8 struct shu{
     9     int w=0x7f7f7f7f7f7f7f,cs;
    10 }a[maxx][maxx];
    11 struct QXX{
    12     int to,xia;
    13 }b[maxn];
    14 int n,m,t,js,N;
    15 int deep[maxn],head[maxn],o[maxn],p[maxn],q[maxn],lsh[maxn],jl[maxn];
    16 int fa[maxn][22];
    17 void add(int x,int y)
    18 {
    19     b[++js].to=y;
    20     b[js].xia=head[x];
    21     head[x]=js;
    22 }
    23 void dfs(int x)
    24 {
    25     for(int i=head[x];i;i=b[i].xia)
    26     {
    27         int ls=b[i].to;
    28         if(deep[ls]==0)
    29         {
    30             deep[ls]=deep[x]+1;  fa[ls][0]=x;
    31             for(int j=1;j<=t;++j)  fa[ls][j]=fa[fa[ls][j-1]][j-1];
    32             dfs(ls);
    33         }
    34     }
    35 }
    36 int LCA(int x,int y)
    37 {
    38     if(deep[x]<deep[y])  swap(x,y);//x的深度大
    39     if(deep[x]!=deep[y])
    40         for(int i=t;i>=0;--i)
    41             if(deep[fa[x][i]]>=deep[y])  x=fa[x][i];
    42     if(x==y)  return y;
    43     for(int i=t;i>=0;--i)
    44         if(fa[x][i]!=fa[y][i])  {x=fa[x][i];  y=fa[y][i];}
    45     return fa[x][0];
    46 }
    47 void bianli(int x)
    48 {
    49     for(int i=head[x];i;i=b[i].xia)
    50     {
    51         int ls=b[i].to;
    52         if(fa[ls][0]==x)
    53         {
    54             bianli(ls);
    55             for(int i=1;i<=N;++i)  a[x][i].cs+=a[ls][i].cs;
    56         }
    57     }
    58 }
    59 int main()
    60 {
    61     scanf("%d%d",&n,&m);  t=log(n)/log(2)+1;
    62     for(int i=1;i<n;++i)
    63     {
    64         int x,y;  scanf("%d%d",&x,&y);
    65         add(x,y);  add(y,x);
    66     }
    67     deep[1]=1;  dfs(1);
    68     for(int i=1;i<=m;++i)
    69     {
    70         scanf("%d%d%d",&o[i],&p[i],&q[i]);
    71         lsh[i]=q[i];  jl[i]=q[i];
    72     }
    73     sort(lsh+1,lsh+m+1);  N=unique(lsh+1,lsh+m+1)-lsh-1;
    74     for(int i=1;i<=m;++i)  q[i]=lower_bound(lsh+1,lsh+N+1,q[i])-lsh;
    75     for(int i=1;i<=m;++i)
    76     {
    77         int z=LCA(o[i],p[i]);
    78         a[o[i]][q[i]].cs++;  a[p[i]][q[i]].cs++;
    79         a[z][q[i]].cs--;  a[fa[z][0]][q[i]].cs--;
    80     }
    81     for(int i=1;i<=n;++i)
    82         for(int j=1;j<=N;++j)  a[i][j].w=lsh[j];
    83     bianli(1);
    84     for(int i=1;i<=n;++i)
    85     {
    86         int zd=0,jj=0x7f7f7f7f7f7f7f;
    87         for(int j=1;j<=N;++j)
    88         {
    89             if(a[i][j].cs>zd)  {zd=a[i][j].cs;  jj=a[i][j].w;}
    90             if(a[i][j].cs==zd&&a[i][j].w<jj)  jj=a[i][j].w;
    91         }
    92         if(zd>0)  printf("%d
    ",jj);
    93         else  printf("0
    ");
    94     }
    95     return 0;
    96 }
    暴力
  • 相关阅读:
    docker 部署springboot
    CentOS 7 安装docker
    008自瞄原理
    007根据矩阵基地址绘制方框
    006寻找矩阵
    005分析其他人基地址
    易语言读取鼠标坐标x,y
    003获取鼠标x,y
    Oracle单机Rman笔记[0]---环境准备
    系统优化设计笔记--曹大公众号文章笔记
  • 原文地址:https://www.cnblogs.com/hzjuruo/p/11270168.html
Copyright © 2020-2023  润新知