【题解】P3258松鼠的新家
2024-09-06 00:08:23
【题解】[P3258 JLOI2014]松鼠的新家
树链剖分板子题。
总结一点容易写错的地方吧:
if(d[top[u]]<d[top[v]]) swap(u,v);
注意是\(top\)。- 在\(dfs2\)中,
if(e[t].to!=r[now]&&e[t].to!=son[now])
注意\(r[now]\)而不是\(last\)
#include<bits/stdc++.h>
using namespace std;
#define RP(t,a,b) for(register int t=(a),edd=(b);t<=edd;++t)
#define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;--t)
#define ERP(t,a) for(register int t=head[a];t;t=e[t].nx)
#define Max(a,b) ((a)<(b)?(b):(a))
#define Min(a,b) ((a)<(b)?(a):(b))
#define midd register int mid=(l+r)>>1
#define TMP template < class ccf >
#define lowbit(x) ((x)&(-(x)))
TMP inline ccf qr(ccf b){
char c=getchar();
int q=1;
ccf x=0;
while(c<48||c>57)
q=c==45?-1:q,c=getchar();
while(c>=48&&c<=57)
x=x*10+c-48,c=getchar();
return q==-1?-x:x;
}
const int maxn=300005;
struct E{
int to,nx;
}e[maxn<<1];
int cnt,n;
int head[maxn];
int mov[maxn];
int toseg[maxn];
int siz[maxn];
int son[maxn];
int top[maxn];
int r[maxn];
int d[maxn];
int seg[maxn];
inline void add(int to,int fr,bool f){
e[++cnt]=(E){to,head[fr]};
head[fr]=cnt;
if(f)
add(fr,to,0);
}
void dfs1(int now,int last){
d[now]=d[last]+1;
r[now]=last;
siz[now]=1;
ERP(t,now){
if(e[t].to!=last){
dfs1(e[t].to,now);
siz[now]+=siz[e[t].to];
if(siz[e[t].to]>siz[son[now]])
son[now]=e[t].to;
}
}
}
void dfs2(int now,int last){
top[now]=last;
toseg[now]=++toseg[0];
if(son[now])
dfs2(son[now],last);
ERP(t,now)
if(e[t].to!=r[now]&&e[t].to!=son[now])
dfs2(e[t].to,e[t].to);
}
inline void basic_add(int x,int tag){
for(register int t=x;t<=n;t+=lowbit(t))seg[t]+=tag;
}
inline void inv_add(int l,int r,int tag){
basic_add(l,tag);basic_add(r+1,-tag);
}
inline void upd(int u,int v){
while(top[u]!=top[v]){
if(d[top[u]]<d[top[v]]) swap(u,v);
inv_add(toseg[top[u]],toseg[u],1);
u=r[top[u]];
}
if(d[u]<d[v]) swap(u,v);
inv_add(toseg[v],toseg[u],1);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
n=qr(1);
RP(t,1,n) mov[t]=qr(1);
for(register int t=2,t1,t2;t<=n;++t)
t1=qr(1),t2=qr(1),add(t1,t2,1);
dfs1(1,0);
dfs2(1,1);
RP(t,1,n-1)
upd(mov[t],mov[t+1]);
RP(t,2,n)
inv_add(toseg[mov[t]],toseg[mov[t]],-1);
RP(t,1,n){
register int ans=0;
for(register int i=toseg[t];i;i-=lowbit(i))
ans+=seg[i];
printf("%d\n",ans);
}
return 0;
}
最新文章
- ASP.NET MVC 初体验
- codevs1048 石子合并
- 将UINavgationController的push改成从左到右
- 关于placeholder中 文字添加换行 用转义字符&;#13;&;#10;代替<;br>;
- js 生成m位随机数入门实例
- 【java基础学习】字符串
- android 两种定时器的实现
- C语言 生成随机数
- linux(centos)下SVN服务器如何搭建
- android 按两次返回键退出应用
- hdu 4742 Pinball Game 3D 分治+树状数组
- iOS 短信验证码倒计时按钮的实现
- 2018-7-27银行卡bin大全-根据银行卡开头查银行
- 小程序picker组件中的(普通选择器:mode = selector)
- 爬虫之urllib
- BZOJ1439 : YY的问题
- 11.15luffycity(7)
- NetMQ 发布订阅模式 Publisher-Subscriber
- 关于windows2008r2系统80端口被system进程占用的问题
- 996ICU的感悟
热门文章
- 多线程一共就俩问题:1.线程安全(访问共享数据) 2.线程通信(wait(),notify())
- CentOS7.0修改主机名(hostname)
- Android开发之布局文件里实现OnClick事件关联处理方法
- PocketBeagle 初高级设置
- HDU 4746 Mophues (莫比乌斯反演应用)
- TCP/IP详解 卷一(第三章 IP:网际协议)
- 数字精确运算BigDecimal经常用法
- CSS环绕球体的旋转文字-3D效果
- 一款炫酷Loading动画--载入成功
- Oracle 修改字段注释