Time Limit: 1000 ms        Memory Limit: 128 MB

[吐槽]

  点分治点分治点分治

  嗯。。场上思考树状数组的时候好像傻掉了。。反正就是挂了就是了。。

[题解]

  首先如果没有环的话就是一道十分简单的点分治啦

  但是这题有环啊

  

  考虑强行变树

  从题目各种谜一般的描述中得出来的结论是:$m<=n$

  其实也就是说最多只有一个环

  那么就有一个很直接的想法,先把唯一的一个环找出来,断掉其中的一条边

  这样就使它变成一棵树了,直接跑一遍点分就好

  考虑断掉的那条边

  这样统计有一个很明显的问题:经过断开那条边的情况全部都没有算进去

  所以现在就考虑怎么算过这条边的ans

  

  首先我们可以将这个环摊开变成这样:

  

  

  然后发现这个东西其实就是一条“链”上面有若干棵树

  断开的那条边显然就是连接这条“链”一头一尾的边(为了方便描述,将这条断开的边记作$(x,y)$)

  我们定义

  $rt_i$表示$i$所属的子树的根节点

  $dis_i$ 表示$i$到$rt_i$的的路径上的点数

  $left_i$表示$rt_i$到这条“链”头(也就是图中编号为1的点)的节点数

  $right_i$表述$rt_i$到这条“链”尾(图中编号为5的点)的节点数

  那么要算一条过$(x,y)$的路径$(i,j)$的点数的话,显然就是子树里面的距离+链上要走的距离

  也就是 $dis_i+dis_j+left_i+right_j$ ($rt_i$在$rt_j$左边)

  

  那么就可以用一个树状数组来搞定了

  考虑怎么统计

  (其实实现起来并不用上面的那些奇妙数组)

  我们可以先将链上的点(也就是各个子树的根节点)编个号

  那么对于一个这条链上面的第$i$和第$j$ $(i<j)$ 个点,那么链上要走的距离就为 $i+(len-j+1)$

  其中$len$表示的是链的长度

  然后将式子上一步中求路径上点数的式子稍微整理一下,得到

  $(dis_i+i)+(dis_j+len-j+1)  (i<j) $

  

  所以我们可以从左往右一个一个点处理

  先将当前点$i$子树内的$dis$处理出来

  然后对于每一个$dis_j (j \in subtree(i))$ ,在树状数组里面查询大于等于$k-dis_j-(len-j+1)$的数量(原因在后面解释)

  查询完了之后将$dis_j+j$丢入树状数组中

  这么处理的原因显然

  整理过后的式子可以分为两部分,分别只与$i$和$j$有关

  然后因为我们是从左到右处理链上面的点的,所以可以保证查询到的点是在当前点的前面的

  然后这题就十分愉快地解决啦

[一些小细节]

  因为这题是求>=的方案数

  所以树状数组要十分愉快地反过来(也就是insert的时候是x-=x&-x,query的时候是x+=x&-x,见代码)

  以及因为insert的时候是dis+i,所以上限应该是2*n

  以及要用long long

  嗯大概就是这样ovo

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int MAXN=;
int h[MAXN],size[MAXN],mx[MAXN];
ll dis[MAXN];
bool vis[MAXN];
int n,m,k,tot,rt,rt_mx;
ll ans,num;
struct xxx
{
int y,next;
bool flag;
}a[MAXN*];
struct data
{
ll c[MAXN*];
int insert(int x,ll delta) {_insert(x,delta);}
int _insert(int x,ll delta)
{
for (;x;x-=x&-x) c[x]+=delta;
}
ll query(int x) {return _query(x);}
ll _query(int x)
{
ll ret=;
if (x<) x=;
for (;x<=*n;x+=x&-x) ret+=c[x];
return ret;
}
}c;
int pre[MAXN],cir[MAXN];
int add(int x,int y);
int dfs(int x);
int dfs_size(int x,int fa);
int dfs_root(int r,int x,int fa);
int get_dis(int x,int fa,int d);
int get_cir(int fa,int x);
ll cal(int x,int d);
bool cmp(int x,int y){return x>y;}
int solve_cir(); int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout); int x,y,z;
scanf("%d%d%d",&n,&m,&k);
tot=;
memset(h,-,sizeof(h));
for (int i=;i<=m;++i)
{
scanf("%d%d",&x,&y);
add(x,y); add(y,x);
}
if (m+==n) {dfs(); printf("%lld\n",ans); return ;}
cir[]=;
get_cir(,);
solve_cir();
} int add(int x,int y)
{
a[++tot].y=y; a[tot].next=h[x]; h[x]=tot; a[tot].flag=true;
} int dfs(int x)
{
rt=,rt_mx=n;
dfs_size(x,);
dfs_root(x,x,);
ans=ans+cal(rt,);
vis[rt]=true;
for (int i=h[rt];i!=-;i=a[i].next)
if (!vis[a[i].y]&&a[i].flag)
{
ans=ans-cal(a[i].y,);
dfs(a[i].y);
}
} int dfs_size(int x,int fa)
{
size[x]=;
mx[x]=;
for (int i=h[x];i!=-;i=a[i].next)
if (a[i].y!=fa&&!vis[a[i].y]&&a[i].flag)
{
dfs_size(a[i].y,x);
size[x]+=size[a[i].y];
mx[x]=max(mx[x],size[a[i].y]);
}
} int dfs_root(int r,int x,int fa)
{
mx[x]=max(mx[x],size[r]-size[x]);
if (rt_mx>mx[x]) rt_mx=mx[x],rt=x;
for (int i=h[x];i!=-;i=a[i].next)
if (a[i].y!=fa&&!vis[a[i].y]&&a[i].flag)
dfs_root(r,a[i].y,x);
} int get_dis(int x,int fa,int d)
{
dis[++num]=d;
for (int i=h[x];i!=-;i=a[i].next)
if (a[i].y!=fa&&!vis[a[i].y]&&a[i].flag)
get_dis(a[i].y,x,d+);
} ll cal(int x,int d)
{
num=;
get_dis(x,,d);
int left=,right=num;
ll re=;
sort(dis+,dis++num,cmp);
while (left<right)
{
while (dis[left]+dis[right]+<k&&left<right) --right;
re+=right-left;
++left;
}
return re;
} int get_cir(int fa,int x)
{
int u;
vis[x]=true; pre[x]=fa;
for (int i=h[x];i!=-;i=a[i].next)
{
u=a[i].y;
if (u==fa) continue;
if (vis[u])
{
a[i].flag=false; a[i^].flag=false;
for (int j=x;j!=u;j=pre[j]) cir[++cir[]]=j;
cir[++cir[]]=u;
return ;
}
get_cir(x,u);
if (cir[]) return ;
}
} int solve_cir()
{
for (int i=;i<=n;++i) vis[i]=false;
dfs();
for (int i=;i<=n;++i) vis[i]=false;
for (int i=;i<=cir[];++i) vis[cir[i]]=true;
for (int i=;i<=cir[];++i)
{
num=;
get_dis(cir[i],,);
for (int j=;j<=num;++j)
ans+=c.query(k-dis[j]-(cir[]-i+));
for (int j=;j<=num;++j)
c.insert(dis[j]+i,);
}
printf("%lld\n",ans);
}

挫挫的代码

【noip模拟】tree的更多相关文章

  1. 8.22 NOIP 模拟题

      8.22 NOIP 模拟题 编译命令 g++ -o * *.cpp gcc -o * *.c fpc *.pas 编译器版本 g++/gcc fpc 评测环境 位 Linux, .3GHZ CPU ...

  2. NOIP 模拟赛

    NOIP 模拟赛 思路:求 n , m 的 gcd,然后用 n , m 分别除以 gcd:若 n 或 m 为偶数,则输出 1/2. 特别的,当 n = m = 1 时,应输出 1/1 #include ...

  3. 8.1 NOIP模拟11

    8.1 NOIP模拟 11 今天上午返校之后,颓了一会,然后下午就开始考试,中午睡着了,然后刚开始考试的时候就困的一匹,我一看T1,woc,这不是之前线段树专题的题啊,和那道题差不多,所以我..... ...

  4. 2019.7.29 NOIP模拟测试10 反思总结【T2补全】

    这次意外考得不错…但是并没有太多厉害的地方,因为我只是打满了暴力[还没去推T3] 第一题折腾了一个小时,看了看时间先去写第二题了.第二题尝试了半天还是只写了三十分的暴力,然后看到第三题是期望,本能排斥 ...

  5. NOIP模拟 17.8.15

    NOIP模拟17.8.15 A 债务文件名 输入文件 输出文件 时间限制 空间限制debt.pas/c/cpp debt.in debt.out 1s 128MB[题目描述]小 G 有一群好朋友,他们 ...

  6. noip模拟23[联·赛·题]

    \(noip模拟23\;solutions\) 怎么说呢??这个考试考得是非常的惨烈,一共拿了70分,为啥呢 因为我第一题和第三题爆零了,然后第二题拿到了70分,还是贪心的分数 第一题和第二题我调了好 ...

  7. noip模拟27[妹子图·腿·腰](fengwu半仙的妹子们)

    \(noip模拟27\;solutions\) 这次吧,我本来以为我能切掉两个题,结果呢??只切掉了一个 不过,隔壁Varuxn也以为能切两个,可惜了,他一个都没切...... 确实他分比我高一点,但 ...

  8. noip模拟6(T2更新

    由于蒟弱目前还没调出T1和T2,所以先写T3和T4.(T1T2更完辣! update in 6.12 07:19 T3 大佬 题目描述: 他发现katarina大佬真是太强了,于是就学习了一下kata ...

  9. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  10. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

随机推荐

  1. NFS工作原理

    很多同学都知道NFS的使用场景,也知道如何配置和使用,但对NFS的工作原理了解的很少. NFS是C/S模式,首先要有一台服务端跑NFS服务,然后各个客户端直接挂载共享目录使用.NFS服务本身不会监听端 ...

  2. eslint规则

    碰到eslint报错, 把错误的提示拷贝在这里Ctrl + F找到复制到eslint.js里面就行了. "off"或者0,不启用这个规则 "warn"或者1,出 ...

  3. IM开发基础知识补课:正确理解前置HTTP SSO单点登陆接口的原理

    1.前言 一个安全的信息系统,合法身份检查是必须环节.尤其IM这种以“人”为中心的社交体系,身份认证更是必不可少. 一些PC时代小型IM系统中,身份认证可能直接做到长连接中(也就是整个IM系统都是以长 ...

  4. Yii2 灵活加载js、css

    Yii2.0对于CSS/js 管理,使用AssetBundle资源包类. 视图如何按需加载CSS/JS ? 资源包定义: backend/assets/AppAsset.PHP <?php na ...

  5. Yii2整合AdminLTE后台主题

    首先你要确保你已经安装好了Yii2 advanced高级模板,并且跑的通. 安装AdminLTE其实没有网上说的那么简单,网上千篇一律的推荐Composer安装,虽然Composer很方便,但是在中国 ...

  6. cf B. Mishka and trip (数学)

    题意   Mishka想要去一个国家旅行,这个国家共有个城市,城市通过道路形成一个环,即第i个城市和第个城市之间有一条道路,此外城市和之间有一条道路.这个城市中有个首中心城市,中心城市与每个城市(除了 ...

  7. 和scikit-learn打个招呼

    1.先装对应的库.不能偷懒,都得装,不然飞不起来. pip install scikit-learn pip install numpy pip install scipy 2.测试如下代码. imp ...

  8. linux及hadoop修改权限

    linux下修改文件权限: 在shell环境里输入:ls -l 或者 ls -lh drwxr-xr-x 2 nsf users 1024 12-10 17:37 下载文件备份对应:文件属性 连接数 ...

  9. __proto__ 与 prototype

    先来做个复习,ES5中有有几种数据类型呢? 5种基本数据类型 Undefined Null Boolean Number String 1种复杂数据类型 Object 除了基本数据类型,万物皆对象,记 ...

  10. 追溯 React Hot Loader 的实现

    文:萝卜(沪江金融前端开发工程师) 本文原创,转载请注明作者及出处 如果你使用 React ,你可以在各个工程里面看到 Dan Abramov 的身影.他于 2015 年加入 facebook,是 R ...