ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【墨西哥区域赛】Carpet

2019-09-21 21:02:48  阅读:198  来源: 互联网

标签:ch 剖分 int hvc 节点 区域 include 墨西哥 Carpet


原题:

题意:

给你一个树,有1e5个节点,让你把这个树放在一个长1e6宽20的网格图里,要求一个格子放一个节点,树边之间不能相交

 

这是一道构造题

因为树的形状可能性很多,很复杂,所以不能简单猜测,而必须要依据某种性质,来保证生成的解一定合法

先尝试小规模,或特殊的问题也是一个重要的思想方法

首先考虑一个节点A和它的所有儿子

不难发现,这时可以把这个节点放在某层,然后把它的儿子放在下一层的一个区间内

只要爸爸出现的顺序和儿子所在区间出现的顺序相同,就不会发生冲突

因为在两层之间连边,斜率只会无限趋于0,所以不会出现于(xA, yA+1)和(xA, yA-1)冲突的情况,只需保证这两层之间的边不相交

继而可以发现,只要满足这个条件,不管A和它的儿子们在什么位置,都不会和别人冲突

为了压缩空间,所有的儿子可以连续放在一起,即使和爸爸相距太远也没有问题

其次,题目数据中宽度为20

根据经验,与众不同的数字往往有重要含义

可以敏感地发现20刚好是log1e6

联系到树链剖分

因为重链剖分保证任意一个节点到根节点的路径最多只会经过logn条重链

所以可以让一条重链躺在一层,而轻儿子都放到下一层,根节点放左上角

这样对于任意一点,想要通过构造的网格图去往根节点,至多会往上爬logn层

所以深度不会超过限制,而宽度显然充足

所以问题就解决了

轻儿子放在连续的区间,区间出现的顺序和爸爸出现的顺序相同,这能保证不发生冲突

进行树链剖分,重链剖分的性质保证深度不会超过限制

 

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 int rd(){int z=0;  char ch=getchar();
 8     while(ch<'0'||ch>'9')  ch=getchar();
 9     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
10     return z;
11 }
12 struct edg{int y,nxt;}e[210000];  int lk[110000],ltp=0;
13 void ist(int x,int y){
14     e[++ltp]=(edg){y,lk[x]};  lk[x]=ltp;
15     e[++ltp]=(edg){x,lk[y]};  lk[y]=ltp;
16 }
17 int n;
18 int fth[110000],hvc[110000],sz[110000];
19 int ax[110000],ay[110000];
20 int hd[30];
21 void dfs1(int x,int y){
22     fth[x]=y;  sz[x]=1;
23     int mx=0,mxid=0;
24     for(int i=lk[x];i;i=e[i].nxt)if(e[i].y!=y){
25         dfs1(e[i].y,x);
26         sz[x]+=sz[e[i].y];
27         if(sz[e[i].y]>mx)  mx=sz[e[i].y],mxid=e[i].y;
28     }
29     hvc[x]=mxid;
30 }
31 void dfs(int x,int y){
32     ay[x]=y,ax[x]=++hd[y];
33     for(int i=lk[x];i;i=e[i].nxt)if(e[i].y!=fth[x] && e[i].y!=hvc[x])
34         dfs(e[i].y,y+1);
35     if(hvc[x])  dfs(hvc[x],y);
36 }
37 int main(){
38     //freopen("ddd.in","r",stdin);
39     memset(lk,0,sizeof(lk));
40     memset(hd,0,sizeof(hd));
41     cin>>n;
42     int l,r;
43     for(int i=1;i<n;++i){
44         l=rd(),r=rd();
45         ist(l,r);
46     }
47     dfs1(1,0);
48     dfs(1,1);
49     for(int i=1;i<=n;++i)  printf("%d %d\n",ax[i],ay[i]);
50     return 0;
51 }
View Code

 

标签:ch,剖分,int,hvc,节点,区域,include,墨西哥,Carpet
来源: https://www.cnblogs.com/cdcq/p/11564565.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有