[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\n",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\n",jj);
93         else  printf("0\n");
94     }
95     return 0;
96 }
暴力

 

posted @ 2019-07-30 15:09  hzoi_X&R  阅读(341)  评论(0编辑  收藏  举报