[BZOJ3307]雨天的尾巴
雨天的尾巴
题目描述
输入格式
输出格式
样例
数据范围与提示
先说说暴力吧,这道题的暴力其实很好想,刚巧上次考试也考到了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 }