【题解】

  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 寝室管理的更多相关文章

  1. BZOJ 3648: 寝室管理( 点分治 + 树状数组 )

    1棵树的话, 点分治+你喜欢的数据结构(树状数组/线段树/平衡树)就可以秒掉, O(N log^2 N). 假如是环套树, 先去掉环上1条边, 然后O(N log^2 N)处理树(同上); 然后再O( ...

  2. 【BZOJ-3648】寝室管理 环套树 + 树状数组 + 点分治

    3648: 寝室管理 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 239  Solved: 106[Submit][Status][Discuss] ...

  3. BZOJ3648 寝室管理 【点分治 + 环套树】

    3648: 寝室管理 Time Limit: 40 Sec  Memory Limit: 512 MB Submit: 366  Solved: 152 [Submit][Status][Discus ...

  4. 【BZOJ3648】寝室管理 树分治

    [BZOJ3648]寝室管理 Description T64有一个好朋友,叫T128.T128是寄宿生,并且最近被老师叫过去当宿管了.宿管可不是一件很好做的工作,碰巧T128有一个工作上的问题想请T6 ...

  5. BZOJ3648 : 寝室管理

    求环套外向树上节点数不小于K的路径数. 首先树的话直接点分治+树状数组$O(n\log^2n)$搞定 环套树的话,先删掉多余的边(a,b) 然后变成了一棵树,直接点分治 然后在树上找到a到b的路径,将 ...

  6. BZOJ3648:寝室管理

    浅谈树分治:https://www.cnblogs.com/AKMer/p/10014803.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem. ...

  7. bzoj3648: 寝室管理(环套树+点分治)

    好题..写了两个半小时hh,省选的时候要一个半小时内调出这种题目还真是难= = 题目大意是给一棵树或环套树,求点距大于等于K的点对数 这里的树状数组做了一点变换.不是向上更新和向下求和,而是反过来,所 ...

  8. BZOJ 4196 软件包管理器

    树链剖分 建树之后,安装软件就是让跟节点到安装的节点路径所有点权+1,卸载软件就是让一个节点和他的子数-1 要求变化数量的话直接求和相减就行啦(绝对值) 注意一点,一开始的lazyatag应该是-1, ...

  9. BZOJ - 4196 软件包管理器 (树链剖分+dfs序+线段树)

    题目链接 设白色结点为未安装的软件,黑色结点为已安装的软件,则: 安装软件i:输出结点i到根的路径上的白色结点的数量,并把结点i到根的路径染成黑色.复杂度$O(nlog^2n)$ 卸载软件i:输出结点 ...

随机推荐

  1. 06_锅炉压力案例_progressbar实现

    相关的native方法可以用javah来生成一个头文件.拿着这个的MainActivity,用它来生成一个头文件. Signature是当前这个方法的方法签名.() V全空参数返回的是void. /* ...

  2. Tomcat优化和JVM分析工具

    Tomcat的常见优化和JVM常见分析工具 Tomcat的常用优化配置 (1) 内存空间: /etc/sysconfig/tomcat JAVA_OPTS="-server -Xms32g ...

  3. 10.9NOIP模拟题

    /* big模拟 细节不少 remove表示这个玩意儿在这一秒有没有移动 注意在一秒内所有小葱一起移动,所以如果一个一个处理 别忘了“错位”这种情况 */ #include<iostream&g ...

  4. 线段树+树状数组+贪心 HDOJ 5338 ZZX and Permutations

    题目传送门 /* 题意:不懂... 线段树+树状数组+贪心:贪心从第一位开始枚举,一个数可以是循环节的末尾或者在循环节中,循环节(循环节内部是后面的换到前面,最前面的换到最后面).线段树维护最大值,树 ...

  5. dos 下小tip

    tip 1:日期的格式化 方法如下: Echo %Date:~0,4%%Date:~5,2%%Date:~8,2%或者Set dt=%Date:~0,4%%Date:~5,2%%Date:~8,2%E ...

  6. Github 文件选择性上传

    用过Github的人都知道.gitignore文件的存在,但是实际用起来还是有一些需要注意的地方,尤其是对于新手来说,稍不注意就会出错.   一.Github选择性忽略特定文件的方式 1.全局设置 一 ...

  7. Android Error:Failed to resolve: com.afollestad:material-dialogs:

    背景: 同事把Android项目直接考给了我...我在Android Studio上运行,然后提示: Error:Failed to resolve: com.afollestad:material- ...

  8. android studio 的Error:No such property: packageApplicationTask for class: com.android.build.gradle.internal.variant.ApkVariantOutputData解决方法

    出现这个原因是安装了jrebel热部署插件,在projectStructure中的projec选项中,android 插件源仓会有热部署的配置.将jcenter后的配置全部删除就可以 注:本人只安装了 ...

  9. win7下安装MySQL 5.7.19(解压缩版)

    1.官网下载地址:https://downloads.mysql.com/archives/community/ 下载后,得到压缩包: 2.解压,我的解压目录为:E:\mysql-5.7.19\mys ...

  10. U盘安装完美的WIN7操作系统教程

    准备工作 首先备份或者在官网下载好您机器的驱动,否则完成后可能无法正常使用 ①一个有win7或者XP系统的电脑(制作启动盘用) ②一个4G以上的U盘 ③win7&win8系统包(请到官网下载或 ...