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

-------------------------------------------------------------------------

#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
 
using namespace std;
 
typedef long long ll;
 
const int maxn = 100009;
 
int N, M, K, e_u, e_v, n, Rt, T, _T, len;
int par[maxn], sz[maxn], mx[maxn], nxt[maxn];
bool vis[maxn];
ll ans;
 
template<class T>
inline void Max(T &x, T t) {
if(t > x) x = t;
}
 
inline int getint() {
char c = getchar();
for(; !isdigit(c); c = getchar());
int ret = 0;
for(; isdigit(c); c = getchar())
ret = ret * 10 + c - '0';
return ret;
}
 
struct edge {
int t;
edge* n;
} E[maxn << 1], *pt = E, *H[maxn];
 
inline void AddEdge(int u, int v) {
pt->t = v, pt->n = H[u], H[u] = pt++;
}
 
void dfs_rt(int x, int fa = -1) {
mx[x] = sz[x] = 1;
for(edge* e = H[x]; e; e = e->n) if(e->t != fa && !vis[e->t]) {
dfs_rt(e->t, x);
sz[x] += sz[e->t];
Max(mx[x], sz[e->t]);
}
Max(mx[x], n - sz[x]);
if(Rt < 0 || mx[x] < mx[Rt]) Rt = x;
}
 
void dfs_sz(int x, int fa = -1) {
sz[x] = 1;
for(edge* e = H[x]; e; e = e->n) if(e->t != fa && !vis[e->t]) {
dfs_sz(e->t, x);
sz[x] += sz[e->t];
}
}
 
struct BIT {
int B[maxn], mk[maxn];
BIT() {
memset(B, 0, sizeof B);
}
inline void Add(int p, int c) {
for(; p <= N; p += p & -p) if(mk[p] != c) {
B[p] = 1;
mk[p] = c;
} else
B[p]++;
}
inline int Sum(int p, int c) {
if(p < 0) return 0;
int ret = 0;
for(; p; p -= p & -p)
if(mk[p] == c) ret += B[p];
return ret;
}
inline int Query(int l, int r, int c) {
return Sum(r, c) - Sum(l - 1, c);
}
} A, B, *CUR[2];
 
void dfs_add(int v, int t, int x, int d, int fa = -1) {
CUR[v]->Add(d++, t);
for(edge* e = H[x]; e; e = e->n)
if(e->t != fa && !vis[e->t]) dfs_add(v, t, e->t, d, x);
}
 
void Solve(int x) {
Rt = -1;
dfs_rt(x);
vis[x = Rt] = true;
dfs_sz(x);
for(edge* e = H[x]; e; e = e->n) if(!vis[e->t]) {
dfs_add(0, ++T, e->t, 1);
for(int i = 1; i <= sz[e->t]; i++)
ans += ll(CUR[0]->Query(i, i, T)) * CUR[1]->Query(K - i, N, Rt);
dfs_add(1, Rt, e->t, 2);
}
ans += CUR[1]->Query(K, N, Rt);
for(edge* e = H[x]; e; e = e->n) if(!vis[e->t]) {
n = sz[e->t];
Solve(e->t);
}
}
 
bool DFS_C(int x, int fa = -1) {
for(edge* e = H[x]; e; e = e->n) if(e->t != fa) {
nxt[e->t] = x;
if(e->t == e_v) {
len = 2;
return true;
}
if(DFS_C(e->t, x)) {
len++;
return true;
}
}
return false;
}
 

void calc(int x, int v, int d) {

vis[x] = true;
_T++;
dfs_add(v, _T, x, d, nxt[x]);
dfs_sz(x, nxt[x]);
for(int i = d; i <= d + sz[x]; i++)
ans += ll(CUR[v]->Query(i, i, _T)) * (CUR[v ^ 1]->Query(K - i, N, T));
dfs_add(v ^ 1, T, x, len - d + 1, nxt[x]);
if(!vis[nxt[x]])
calc(nxt[x], v, d - 1);
}
 
void Work() {
CUR[0] = &A, CUR[1] = &B;
memset(vis, 0, sizeof vis);
n = N;
Solve(T = 0);
if(M < N) {
cout << ans << endl;
return;
}
A = BIT(), B = BIT();
CUR[0] = &A, CUR[1] = &B;
T = _T = 0;
DFS_C(e_u);
nxt[e_u] = e_v;
++T;
memset(vis, 0, sizeof vis);
vis[e_v] = true;
dfs_add(0, T, e_v, 1, nxt[e_v]);
calc(nxt[e_v], 1, len - 1);
cout << ans << "\n";
}
 
int Find(int x) {
return x == par[x] ? x : par[x] = Find(par[x]);
}
 
void Init() {
N = getint(), M = getint(), K = getint();
for(int i = 0; i < N; i++) par[i] = i;
for(int i = 0; i < M; i++) {
int u = getint() - 1, v = getint() - 1;
int _u = Find(u), _v = Find(v);
if(_u != _v) {
par[_u] = _v;
AddEdge(u, v);
AddEdge(v, u);
} else
e_u = u, e_v = v;
}
ans = 0;
}
 
int main() {
Init();
Work();
return 0;
}

-------------------------------------------------------------------------

3648: 寝室管理

Time Limit: 40 Sec  Memory Limit: 512 MB
Submit: 136  Solved: 67
[Submit][Status][Discuss]

Description

T64有一个好朋友,叫T128。T128是寄宿生,并且最近被老师叫过去当宿管了。宿管可不是一件很好做的工作,碰巧T128有一个工作上的问题想请T64帮忙解决。
  T128的寝室条件不是很好,所以没有很多钱来装修。礼间寝室仅由n-1条双向道路连接,而且任意两间寝室之间都可以互达。最近,T128被要求对一条路径上的所有寝室进行管理,这条路径不会重复经过某个点或某条边。但他不记得是哪条路径了。他只记得这条路径上有不少于k个寝室。于是,他想请T64帮忙数一下,有多少条这样的路径满足条件。
    嗯…还有一个问题。由于最近有一些熊孩子不准晚上讲话很不爽,他们决定修筑一条“情报通道”,如果通道建成,寝室就变成了一个N个点N条边的无向图。并且,经过“情报通道”的路径也是合法的。T128心想:通道建成之前,T64还有一个高效的算法帮我数路径条数,但是通道建成之后,他还有办法吗?对,T64手忙脚乱,根本数不清有多少条路径。于是他找到了你。

Input

第一行为三个正整数N,M,K(2 ≤ K ≤ N),代表有n间寝室,m条边连接它们n-1 ≤ m ≤ N;m= n-1意味着“情报遁道”未被修好;m=n意味着“情报通道”已被修好),以及题目描述中的K。
  接下来m行,每行两个正整数z,y,代表第x间寝室与第y间寝室之间有一条双向边。

Output

仅包含一个整数,代表经过至少K间寝室的路径条数。

Sample Input

5 5
1 3
2 4
3 5
4 1
5 2

Sample Output

20

HINT

N≤100000

K≤N

M=N

Source

BZOJ 3648: 寝室管理( 点分治 + 树状数组 )的更多相关文章

  1. BZOJ 2683 简单题 cdq分治+树状数组

    题意:链接 **方法:**cdq分治+树状数组 解析: 首先对于这道题,看了范围之后.二维的数据结构是显然不能过的.于是我们可能会考虑把一维排序之后还有一位上数据结构什么的,然而cdq分治却可以非常好 ...

  2. BZOJ 1176: [Balkan2007]Mokia( CDQ分治 + 树状数组 )

    考虑cdq分治, 对于[l, r)递归[l, m), [m, r); 然后计算[l, m)的操作对[m, r)中询问的影响就可以了. 具体就是差分答案+排序+离散化然后树状数组维护.操作数为M的话时间 ...

  3. bzoj 3730 震波——动态点分治+树状数组

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3730 查询一个点可以转化为查询点分树上自己到根的路径上每个点对应范围答案.可用树状数组 f ...

  4. bzoj 3730 震波 —— 动态点分治+树状数组

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3730 建点分树,每个点记两个树状数组,存它作为重心管辖的范围内,所有点到它的距离情况和到它在 ...

  5. BZOJ 1176 Mokia CDQ分治+树状数组

    1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1854  Solved: 821[Submit][St ...

  6. BZOJ_3262_陌上花开_CDQ分治+树状数组

    BZOJ_3262_陌上花开_CDQ分治+树状数组 Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的 ...

  7. 【BZOJ4553】[Tjoi2016&Heoi2016]序列 cdq分治+树状数组

    [BZOJ4553][Tjoi2016&Heoi2016]序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能 ...

  8. 【bzoj3262】陌上花开 CDQ分治+树状数组

    题目描述 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa&g ...

  9. 【bzoj2225】[Spoj 2371]Another Longest Increasing CDQ分治+树状数组

    题目描述 给定N个数对(xi, yi),求最长上升子序列的长度.上升序列定义为{(xi, yi)}满足对i<j有xi<xj且yi<yj. 样例输入 8 1 3 3 2 1 1 4 5 ...

随机推荐

  1. pl sql练习(2)

    1.尽可能了解oracle的功能,因为很多业务逻辑oracle已经为我们做了,比如oracle已经预定义了大量的异常代码,我们不必要写自己的异常而增加代码的复杂度. 例如oracle定义了当找不到符合 ...

  2. zookeeper_01:zookeeper概述

    应对场景: 相对于开发在一台计算机上运行的单个程序,如何让一个应用中的多个独立的程序协同工作是一件非常困难的事情.开发这样的应用,很容易让很多开发人员陷入如何使多个程序协同工作的逻辑中,最后导致没有时 ...

  3. Windows下Vundle安装

    鼠标手老是发作,没办法.想学习vim尽量减少编码时使用鼠标的频率.安装好gVim开始安装Vundle插件,总结下安装过程和各种遇到的坑: github上VundleVim倒是有说明 Windows S ...

  4. arm str 指令

    str 指令格式: str{条件} 1源寄存器 ,2存储器地址 eg: str r0,[r1],#8;将r0中的数值赋值给r1,然后在r1地址上+立即数8,再写入r1中: str r0,[r1,#8] ...

  5. ComboGrid 行内点击编辑内容

    最近easyui需要在行内编辑选中项,但是编辑的内容出了当前选中列值,还有其他的,比较麻烦, 先看下这段代码 columns: [[ { field: 'GuestID', title: '编号', ...

  6. oracle中导出导入表以及数据

    Oracle数据导入导出imp/exp就相当于oracle数据还原与备份.exp命令可以把数据从远程数据库服务器导出到本地的dmp文件,imp命令可以把dmp文件从本地导入到远处的数据库服务器中.利用 ...

  7. Oracle数据库中如何选择合适的索引类型 .

    索引就好象一本字典的目录.凭借字典的目录,我们可以非常迅速的找到我们所需要的条目.数据库也是如此.凭借Oracle数据库的索引,相关语句可以迅速的定位记录的位置,而不必去定位整个表. 虽然说,在表中是 ...

  8. Android中使用开源框架android-image-indicator实现图片轮播部署

    之前的博文中有介绍关于图片轮播的实现方式,分别为(含超链接): 1.<Android中使用ViewFlipper实现屏幕切换> 2.<Android中使用ViewPager实现屏幕页 ...

  9. (2012年旧文)纪念史蒂夫乔布斯---IT界的普罗米修斯

    谈苹果与乔布斯系列一  IT界的普罗米修斯 纪念PC界的先驱 史蒂夫乔布斯 2012-4-5 清明节,纪念IT时代的开创人—伟大的史蒂夫 乔布斯. 没有乔布斯,计算机还是属于一群科技人士的工具,没有漂 ...

  10. Unable to execute dex: Multiple dex files define Lorg/ap (

    解决这个问题的方法,直接把commons-collections.jar这个jar包删除,一定要删干净啊,各个地方看一下,再clean下,应该没问题了!根据这个英文的目录指示就是Unable to e ...