BZOJ3648:寝室管理
浅谈树分治:https://www.cnblogs.com/AKMer/p/10014803.html
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3648
基环树分治,结合了点分和边分的思想。
先随便拆掉环上一条边,我们先称它为基边,把它当做树做一遍,跟Free Tour II差不多。
剩下的问题就是如何统计经过基边的路径条数了。我们将基边连着的两个点分别成为\(st\)和\(ed\),\(st\)的顺时针方向是\(ed\),\(ed\)的逆时针方向是\(st\)。直接跟边分一样去分别处理\(st\)和\(ed\)能延伸出去的路径长度不行,因为这样会在环上产生交集然后统计不合法的路径。所以我们枚举基边以外的边去断开再统计答案,就可以保证统计出来的答案不重不漏了。
然后因为只要做一遍,所以大力树状数组也没关系。
时间复杂度:\(O(nlogn)\)
空间复杂度:\(O(n)\)
代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
#define low(i) ((i)&(-(i)))
const int maxn=1e5+5;
ll ans;
bool vis[maxn],bo;
int n,m,limit,tot=1,id,mx,rt,N;
int now[maxn],pre[maxn*2],son[maxn*2];
int siz[maxn],f[maxn],g[maxn],depest[maxn],V[maxn];
int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
void add(int a,int b) {
pre[++tot]=now[a];
now[a]=tot,son[tot]=b;
}
struct TreeArray {
int c[maxn];
void change(int pos,int v) {
if(pos==n-13)mx++;
for(int i=pos;i<=n;i+=low(i))
c[i]+=v;
}
int query(int pos) {
int res=0;
for(int i=pos;i;i-=low(i))
res+=c[i];
return res;
}
}T;
struct ring {
int node1,node2;
int dis[maxn],nxt[maxn],lst[maxn];
bool find_ring(int fa,int u) {
vis[u]=1;
for(int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if(v!=fa) {
if(vis[v])id=p>>1,node1=v,node2=u;
if(vis[v]||find_ring(u,v)) {
nxt[u]=v,lst[v]=u;
return 1;
}
}
return 0;
}
void dfs(int fa,int u,int num) {
if(num==1)dis[u]=dis[fa]+1;
T.change(n-dis[u]+1,num);
for(int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if(!vis[v]&&v!=fa)dfs(u,v,num);
}
void query(int fa,int u) {
dis[u]=dis[fa]+1,ans+=T.query(n-(max(1,limit-dis[u]))+1);
for(int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if(!vis[v]&&v!=fa)query(u,v);
}
void work() {
lst[node1]=node2;
memset(vis,0,sizeof(vis));
int st=son[id<<1],ed=son[id<<1|1];
if(nxt[st]==ed)swap(st,ed);
int pos=st;vis[ed]=1;
while(pos!=ed)vis[pos]=1,pos=nxt[pos];
dis[ed]=0,pos=st;mx=0;
while(pos!=ed)dfs(lst[pos],pos,1),pos=nxt[pos];dfs(lst[ed],ed,1);
pos=ed;dis[st]=0;
while(pos!=st)dfs(nxt[pos],pos,-1),query(nxt[pos],pos),pos=lst[pos];
}
}R;
void find_rt(int fa,int u) {
int res=0;siz[u]=1;
for(int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if(!vis[v]&&(p>>1)!=id&&v!=fa)
find_rt(u,v),siz[u]+=siz[v],res=max(res,siz[v]);
res=max(res,N-siz[u]);
if(res<mx)mx=res,rt=u;
}
void dfs(int fa,int u,int dep) {
mx=max(mx,dep),siz[u]=1;
for(int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if(!vis[v]&&(p>>1)!=id&&v!=fa)
dfs(u,v,dep+1),siz[u]+=siz[v];
}
bool cmp(int a,int b) {
return depest[a]<depest[b];
}
void query(int fa,int u,int dep) {
ans+=f[max(1,limit-dep)];
for(int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if(!vis[v]&&v!=fa&&(p>>1)!=id)query(u,v,dep+1);
}
void solve(int fa,int u,int dep) {
g[dep]++;
for(int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if(!vis[v]&&v!=fa&&(p>>1)!=id)solve(u,v,dep+1);
}
void work(int u,int size) {
N=size,mx=rt=n+1,find_rt(0,u),u=rt,vis[u]=1,tot=0;
for(int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if(!vis[v]&&(p>>1)!=id) {
V[++tot]=v,mx=0;
dfs(u,v,2),depest[v]=mx;
}
sort(V+1,V+tot+1,cmp);
for(int i=1;i<=tot;i++) {
query(u,V[i],1);
solve(u,V[i],2);
for(int j=depest[V[i]];j;j--)
g[j]+=g[j+1],f[j]+=g[j];
for(int j=1;j<=depest[V[i]];j++)g[j]=0;
}
ans+=f[limit];
for(int i=1;i<=depest[V[tot]];i++)f[i]=g[i]=0;
for(int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if(!vis[v]&&(p>>1)!=id)work(v,siz[v]);
}
int main() {
n=read(),m=read(),limit=read();
for(int i=1;i<=m;i++) {
int a=read(),b=read();
add(a,b),add(b,a);
}
if(m==n)R.find_ring(0,1);
memset(vis,0,sizeof(vis));
work(1,n);
if(m==n)R.work();
printf("%lld\n",ans);
return 0;
}
BZOJ3648:寝室管理的更多相关文章
- BZOJ3648 寝室管理 【点分治 + 环套树】
3648: 寝室管理 Time Limit: 40 Sec Memory Limit: 512 MB Submit: 366 Solved: 152 [Submit][Status][Discus ...
- bzoj3648: 寝室管理(环套树+点分治)
好题..写了两个半小时hh,省选的时候要一个半小时内调出这种题目还真是难= = 题目大意是给一棵树或环套树,求点距大于等于K的点对数 这里的树状数组做了一点变换.不是向上更新和向下求和,而是反过来,所 ...
- BZOJ3648 : 寝室管理
求环套外向树上节点数不小于K的路径数. 首先树的话直接点分治+树状数组$O(n\log^2n)$搞定 环套树的话,先删掉多余的边(a,b) 然后变成了一棵树,直接点分治 然后在树上找到a到b的路径,将 ...
- 【BZOJ3648】寝室管理 树分治
[BZOJ3648]寝室管理 Description T64有一个好朋友,叫T128.T128是寄宿生,并且最近被老师叫过去当宿管了.宿管可不是一件很好做的工作,碰巧T128有一个工作上的问题想请T6 ...
- 【BZOJ-3648】寝室管理 环套树 + 树状数组 + 点分治
3648: 寝室管理 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 239 Solved: 106[Submit][Status][Discuss] ...
- BZOJ 3648: 寝室管理( 点分治 + 树状数组 )
1棵树的话, 点分治+你喜欢的数据结构(树状数组/线段树/平衡树)就可以秒掉, O(N log^2 N). 假如是环套树, 先去掉环上1条边, 然后O(N log^2 N)处理树(同上); 然后再O( ...
- BZOJ 3648 寝室管理
[题解] GDOI2016 Day2T3 如果给出的数据是一棵树那么皆大欢喜直接点分治就好了,用树状数组维护大于x的数的个数.如果是一棵基环树,我们先断掉环上的一条边,然后跑点分治:再加上经过这条边的 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- 第五次作业——Alpha项目测试
第五次作业——Alpha项目测试 格式描述: 这个作业属于哪个课程 2019秋软工17级系统分析与设计 这个作业要求在哪里 作业要求 团队名称 杨荣模杰和他的佶祥虎 这个作业的目标 测试其他组项目并写 ...
随机推荐
- springboot输出日志到指定目录,简单粗暴,springboot输出mybatis日志
springboot官方文档地址https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot- ...
- spring boot 发布成包所需插件
在pom.xml里配置 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId> ...
- EasyPlayer RTSP Windows播放器D3D,GDI的几种渲染方式的选择区别
EasyPlayer-RTSP windows播放器支持D3D和GDI两种渲染方式,其中D3D支持格式如下: DISPLAY_FORMAT_YV12 DISPLAY_FORMAT_YUY2 DISPL ...
- JS学习总结之操作文档对象模型
操作文档对象模型 DOM 结构树 文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可拓展置标语言的标准编程接口.它是一种与平台和语言无关的应用程序接口(A ...
- HTML 学习笔记 JQuery(锋利的JQuery 代码)
一 制作简单的导航栏 <html> <head> <meta charset="UTF-8"> <title></title& ...
- 远程服务器上的weblogic项目管理(四)filelock not found错误解决方法
重启weblogic时如果有残余进程没有kill,启动时便可能会造成filelock not found,文件锁未找到错误,解决方法如下: 删掉Domain下的*.lok文件:(如果不熟悉文件路径推荐 ...
- 【题解】Sumdiv
[题解]Sumdiv 传送门 根据组合的乘法原理,一个数的所有约数和 \[ sum=\prod_{i=1} \Sigma_j^{a_i} p_i^j \] 所以任务就变成了分解\(A\)的质因数,分解 ...
- LeetCode——Binary Tree Postorder Traversal
Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary ...
- Halcon下载、安装
下载地址: 官网:http://www.halcon.com/halcon/download/ Halcon学习网:http://www.ihalcon.com/read.php?tid=56 { 最 ...
- [IR课程笔记]Query Refinement and Relevance Feedback
相关反馈的两种类型: “真实”的相关反馈: 1. 系统返回结果 2. 用户提供一些反馈 3. 系统根据这些反馈,返回一些不同的,更好的结果 “假定”的相关反馈 1. 系统得到结果但是并不返回结果 2. ...