BZOJ 3648 寝室管理

【题解】
GDOI2016 Day2T3
如果给出的数据是一棵树那么皆大欢喜直接点分治就好了,用树状数组维护大于x的数的个数。如果是一棵基环树,我们先断掉环上的一条边,然后跑点分治;再加上经过这条边的方案数,其实就是从断掉的那条边的一个端点开始,把环遍历一遍,更新贡献的方式跟点分治过程中的差不多,具体看注释2333。
#include<cstdio>
#include<algorithm>
#define rg register
#define N 100010
#define LL long long
using namespace std;
int n,m,k,tot,cnt,top,cir,root;
int last[N],dep[N],bit[N<<],siz[N],mxsiz[N],st[N],c[N];
bool cut[N<<],v[N];
LL ans=;
struct edge{
int to,pre,dis;
}e[N<<];
inline int read(){
int k=,f=; char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(''<=c&&c<='')k=k*+c-'',c=getchar();
return k*f;
}
inline void add(int x,int y){for(;x>;x-=(x&-x))bit[x]+=y;}
inline int query(int x){
if(x<) x=; int ret=;
for(;x<=n+cir;x+=(x&-x)) ret+=bit[x]; return ret;
}
void findcircle(int x,int fa){
if(cir) return;
if(v[x]){
c[cir=]=x;
for(rg int i=top;st[i]!=x;c[++cir]=st[i--]);
}
v[x]=; st[++top]=x;
for(rg int i=last[x],to;i;i=e[i].pre)
if((to=e[i].to)!=fa) findcircle(to,x);
v[x]=; top--;
}
void getroot(int x,int fa){
siz[x]=; mxsiz[x]=;
for(rg int i=last[x],to;i;i=e[i].pre)if(!v[to=e[i].to]&&to!=fa&&!cut[i]){
getroot(to,x); siz[x]+=siz[to];
mxsiz[x]=max(mxsiz[x],siz[to]);
}
mxsiz[x]=max(mxsiz[x],cnt-mxsiz[x]);
if(!root||mxsiz[x]<mxsiz[root]) root=x;
}
void getdep(int x,int fa,int d){
st[++top]=d;
for(rg int i=last[x],to;i;i=e[i].pre)
if(!v[to=e[i].to]&&to!=fa&&!cut[i]) getdep(to,x,d+);
}
void dfs(int x){
int l=; v[x]=;
for(rg int i=last[x],to;i;i=e[i].pre)
if(!v[to=e[i].to]&&!cut[i]){
l=top+; getdep(to,x,);
for(rg int j=l;j<=top;j++) ans+=query(k-st[j]-);
for(rg int j=l;j<=top;j++) add(st[j],);
}
ans+=query(k-);
while(top) add(st[top--],-);
for(rg int i=last[x],to;i;i=e[i].pre)
if(!v[to=e[i].to]&&!cut[i]&&siz[to]>=k){
cnt=siz[to]; root=; getroot(to,x); dfs(root);
}
}
int main(){
n=read(); m=read(); k=read();
for(rg int i=;i<=m;i++){
int u=read(),v=read();
e[++tot]=(edge){v,last[u]}; last[u]=tot;
e[++tot]=(edge){u,last[v]}; last[v]=tot;
}
if(m<n){
cnt=n; root=; getroot(,); dfs(root);
}
else{
findcircle(,);
for(rg int i=last[c[]],to;i;i=e[i].pre)if((to=e[i].to)==c[cir]){
cut[i]=; break;
}
for(rg int i=last[c[cir]],to;i;i=e[i].pre)if((to=e[i].to)==c[]){
cut[i]=; break;
}
top=; cnt=n; root=;
getroot(,); dfs(root);
top=;
for(rg int i=;i<=n;i++)v[i]=;
for(rg int i=;i<=cir+n;i++) bit[i]=;
for(rg int i=;i<=cir;i++) v[c[i]]=;
for(rg int i=;i<=cir;i++){
v[c[i]]=;
getdep(c[i],,);
v[c[i]]=;
for(rg int j=;j<=top;j++)ans+=query(k-(cir-i+)-st[j]);//cir-i+1是绕一圈到环上起点的距离
while(top) add(st[top--]+i,);//+i就是加上到环上起点的距离
}
}
printf("%lld\n",ans);
return ;
}
BZOJ 3648 寝室管理的更多相关文章
- BZOJ 3648: 寝室管理( 点分治 + 树状数组 )
1棵树的话, 点分治+你喜欢的数据结构(树状数组/线段树/平衡树)就可以秒掉, O(N log^2 N). 假如是环套树, 先去掉环上1条边, 然后O(N log^2 N)处理树(同上); 然后再O( ...
- 【BZOJ-3648】寝室管理 环套树 + 树状数组 + 点分治
3648: 寝室管理 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 239 Solved: 106[Submit][Status][Discuss] ...
- BZOJ3648 寝室管理 【点分治 + 环套树】
3648: 寝室管理 Time Limit: 40 Sec Memory Limit: 512 MB Submit: 366 Solved: 152 [Submit][Status][Discus ...
- 【BZOJ3648】寝室管理 树分治
[BZOJ3648]寝室管理 Description T64有一个好朋友,叫T128.T128是寄宿生,并且最近被老师叫过去当宿管了.宿管可不是一件很好做的工作,碰巧T128有一个工作上的问题想请T6 ...
- BZOJ3648 : 寝室管理
求环套外向树上节点数不小于K的路径数. 首先树的话直接点分治+树状数组$O(n\log^2n)$搞定 环套树的话,先删掉多余的边(a,b) 然后变成了一棵树,直接点分治 然后在树上找到a到b的路径,将 ...
- BZOJ3648:寝室管理
浅谈树分治:https://www.cnblogs.com/AKMer/p/10014803.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem. ...
- bzoj3648: 寝室管理(环套树+点分治)
好题..写了两个半小时hh,省选的时候要一个半小时内调出这种题目还真是难= = 题目大意是给一棵树或环套树,求点距大于等于K的点对数 这里的树状数组做了一点变换.不是向上更新和向下求和,而是反过来,所 ...
- BZOJ 4196 软件包管理器
树链剖分 建树之后,安装软件就是让跟节点到安装的节点路径所有点权+1,卸载软件就是让一个节点和他的子数-1 要求变化数量的话直接求和相减就行啦(绝对值) 注意一点,一开始的lazyatag应该是-1, ...
- BZOJ - 4196 软件包管理器 (树链剖分+dfs序+线段树)
题目链接 设白色结点为未安装的软件,黑色结点为已安装的软件,则: 安装软件i:输出结点i到根的路径上的白色结点的数量,并把结点i到根的路径染成黑色.复杂度$O(nlog^2n)$ 卸载软件i:输出结点 ...
随机推荐
- bzoj3295 洛谷P3157、1393 动态逆序对——树套树
题目:bzoj3295 https://www.lydsy.com/JudgeOnline/problem.php?id=3295 洛谷 P3157(同一道题) https://www.luogu.o ...
- Permutations II 典型去重
https://leetcode.com/problems/permutations-ii/ Given a collection of numbers that might contain dupl ...
- java笔记线程方式1睡眠
public class ThreadSleepDemo { public static void main(String[] args) { ThreadSleep ts1 = new Thread ...
- 基于PHP自带的mail函数实现发送邮件以及带有附件的邮件功能
PHPmail函数简介 bool mail ( string $to , string $subject , string $message [, string $additional_headers ...
- bzoj 1619: [Usaco2008 Nov]Guarding the Farm 保卫牧场【bfs】
不是严格小于是小于等于啊!!!!!不是严格小于是小于等于啊!!!!!不是严格小于是小于等于啊!!!!! 是我看不懂人话还是翻译不说人话= = 把所有格子按值排个序,bfs扩展打标记即可 #includ ...
- React实战之Ant Design—Upload上传_附件上传
React实战之Ant Design—Upload上传_附件上传 Upload组件大家都在官方文档中看过了,但写的时候还是会遇到许多问题,一些新手看了文档后感觉无从下手,本文过多的简绍就不说了,直接看 ...
- mui 文件上传注意问题
1. mui 文件上传 key对应后台接收参数名,但对对于多文件上传就没办法了,addFile 的key不能重复 task.addFile( "_www/a.doc", {key: ...
- Linux环境下修改MySQL数据库对表名大小写不敏感
Linux系统中MySQL对数据库名称和表名是大小写敏感的,这就导致了一些麻烦,虽然已经建立了表和数据,但因为大小写导致无法找到表. MySQL数据库对表名大小写不敏感的设置方法如下: 1.查看MyS ...
- Oracle11gR2设置连接数process与会话session值
近日构建的Web应用用户数量有所上升,后台总是打印无法打开数据库连接的错误信息: 000000a3 SystemOut O 9月 ::, ERROR - msg:打开数据库出错. 经查询发现需要更改数 ...
- ASP.NET中的<%%>介绍
一.主要用于ASP.NET前台绑定用的最多: <%#Eval("")%> <%#Bind("")%> <%=变量%> 1.& ...