题目:http://codeforces.com/contest/293/problem/E

仍旧是点分治。用容斥,w的限制用排序+两个指针解决, l 的限制就用树状数组。有0的话就都+1,相对大小不变。

切勿每次memset!!!会T得不行。add(sta[ l ].len)即可,但要判一下(l==r)以防不测。(真的有那种数据!)

最后注意树状数组的范围是L(即L+1),不是n。不然可以尝试:

2 10 12

1 5

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=1e5+;
int n,L,W,hd[N],xnt,to[N<<],nxt[N<<],w[N<<];
int mn,rt,f[N],l,r,siz[N],lm;
ll ans;
bool vis[N];
struct Sta{
int w,len;Sta(int w=,int l=):w(w),len(l) {}
bool operator< (const Sta &b)const
{return w==b.w?len<b.len:w<b.w;}
}sta[N];
void add(int x,int y,int z)
{
to[++xnt]=y;nxt[xnt]=hd[x];w[xnt]=z;hd[x]=xnt;
to[++xnt]=x;nxt[xnt]=hd[y];w[xnt]=z;hd[y]=xnt;
}
void getrt(int cr,int fa,int s)
{
siz[cr]=;int mx=;
for(int i=hd[cr],v;i;i=nxt[i]) if(!vis[v=to[i]]&&v!=fa)
{
getrt(v,cr,s);siz[cr]+=siz[v];mx=max(mx,siz[v]);
}
mx=max(mx,s-siz[cr]);
if(mx<mn)mn=mx,rt=cr;
}
void add(int x,int k){x++;for(;x<=lm;x+=(x&-x))f[x]+=k;}//x<=L+1!!!
int query(int x){x++;int ret=;for(;x;x-=(x&-x))ret+=f[x];return ret;}
void dfs(int cr,int fa,int pw,int pl)
{
if(pw>W||pl>L)return;
sta[++r]=Sta(pw,pl);add(sta[r].len,);
for(int i=hd[cr],v;i;i=nxt[i]) if(!vis[v=to[i]]&&v!=fa)
dfs(v,cr,pw+w[i],pl+);
}
ll calc(int cr,int pw,int pl)
{
l=;r=;dfs(cr,,pw,pl);
sort(sta+l,sta+r+);///////
// printf("l=%d r=%d\n",l,r);
// for(int i=l;i<=r;i++)printf("sta[%d].w=%d .len=%d\n",i,sta[i].w,sta[i].len);
ll ret=;
while(l<r)
if(sta[l].w+sta[r].w>W)add(sta[r--].len,-);
else ret+=query(L-sta[l].len)-(sta[l].len<=L-sta[l].len),
// printf("l=%d r=%d query(%d)=%d\n"
// ,l,r,L-sta[l].len,query(L-sta[l].len)),
add(sta[l++].len,-);
if(l==r)add(sta[l].len,-);
// memset(f,0,sizeof f);///TLE!!!!!
return ret;
}
void solve(int cr,int s)
{
// printf("cr=%d\n",cr);
vis[cr]=;ans+=calc(cr,,);
// printf("cr=%d ans=%lld\n",cr,ans);
for(int i=hd[cr],v;i;i=nxt[i]) if(!vis[v=to[i]])
{
ans-=calc(v,w[i],);
// printf("(cr=%d ans=%lld)(v=%d)\n",cr,ans,v);
int ts=(siz[cr]>siz[v]?siz[v]:s-siz[cr]);
mn=N;getrt(v,,ts);solve(rt,ts);
}
}
int main()
{
scanf("%d%d%d",&n,&L,&W);lm=L+;
for(int i=,y,z;i<=n;i++)
{
scanf("%d%d",&y,&z);add(i,y,z);
}
mn=N;getrt(,,n);solve(rt,n);
printf("%I64d\n",ans);
return ;
}

CF 293E Close Vertices——点分治的更多相关文章

  1. CodeForces 293E Close Vertices 点分治

    题目传送门 题意:现在有一棵树,每条边的长度都为1,然后有一个权值,求存在多少个(u,v)点对,他们的路劲长度 <= l, 总权重 <= w. 题解: 1.找到树的重心. 2.求出每个点到 ...

  2. codeforces 293E Close Vertices

    题目链接 正解:点分治+树状数组. 点分治板子题,直接点分以后按照$w$排序,扫指针的时候把$w$合法的路径以$l$为下标加入树状数组统计就行了. 写这道题只是想看看我要写多久..事实证明我确实是老年 ...

  3. CF 716E. Digit Tree [点分治]

    题意:一棵树,边上有一个个位数字,走一条路径会得到一个数字,求有多少路径得到的数字可以整除\(P\) 路径统计一般就是点分治了 \[ a*10^{deep} + b \ \equiv \pmod P\ ...

  4. ●CodeForce 293E Close Vertices

    题链: http://codeforces.com/contest/293/problem/E题解: 点分治,树状数组 大致思路和 POJ 1741 那道点分治入门题相同, 只是因为多了一个路径的边数 ...

  5. CF293E Close Vertices 点分治+树状数组

    开始zz写了一个主席树,后来发现写个树状数组就行~ #include <cstdio> #include <vector> #include <algorithm> ...

  6. CF 293 E Close Vertices (树的分治+树状数组)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题目:给出一棵树,问有多少条路径权值和不大于w,长 ...

  7. cf293E Close Vertices(树分治+BIT)

    E. Close Vertices You've got a weighted tree, consisting of n vertices. Each edge has a non-negative ...

  8. Codeforces 293E 点分治+cdq

    Codeforces 293E 传送门:https://codeforces.com/contest/293/problem/E 题意: 给你一颗边权一开始为0的树,然后给你n-1次操作,每次给边加上 ...

  9. CF 322E - Ciel the Commander 树的点分治

    树链剖分可以看成是树的边分治,什么是点分治呢? CF322E - Ciel the Commander 题目:给出一棵树,对于每个节点有一个等级(A-Z,A最高),如果两个不同的节点有相同等级的父节点 ...

随机推荐

  1. Netty ByteBuf(图解之 2)| 秒懂

    目录 Netty ByteBuf(图解二):API 图解 源码工程 写在前面 ByteBuf 的四个逻辑部分 ByteBuf 的三个指针 ByteBuf 的三组方法 ByteBuf 的引用计数 Byt ...

  2. Django 基于Ajax & form 简单实现文件上传

    前端实现 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="U ...

  3. print函数详解及python打印99乘法表的不同方法

    首先你需要了解print的原型,并且要知道在python2和python3中print函数功能不同,不只是表现在后面带不带()一方面! 在python3中,通过help(print)可以得到print ...

  4. PHP数据库链接类(PDO+Access)实例分享

    这篇文章主要介绍了PHP数据库链接类(PDO+Access),有需要的朋友可以参考一下 PHP PDO Access链接 复制代码代码如下: class DbHelpClass     {       ...

  5. linux查看当前文件夹下每个文件大小

    查看当前文件夹下每个文件大小 并会给出当前文件大小总和,后面加具体的文件名会显示具体的文件大小 ls -lht 把*换成具体的文件名会显示具体的文件大小 du -sh *

  6. Python基础(1)_python介绍、简单运算符

    Python执行一个程序分为三个阶段 阶段一:先启动python解释器 阶段二:python解释器把硬盘中的文件读入到内存中 阶段三:python解释器解释执行刚刚读入内存的代码 二.编程语言的分类: ...

  7. linux 指令(经常更新)

    添加一个服务 # sudo update-rc.d 服务名 defaults 99 删除一个服务 # sudo update-rc.d 服务名 remove 临时重启一个服务 # /etc/init. ...

  8. ubuntu14.04 安装pip vitualenv flask

    安装pip: $ apt-get install python-pip$ pip -V #查看版本 确认安装成功 安装完pip后,会发现下载的速度特别慢.按如下修改: $ vim ~/.pip/pip ...

  9. Ubuntu14 下安装jdk1.8

    1.oracle官网下载jdk-8u45-linux-i586.gz 此为32位 2.放在任意目录下,如/home/hongxf 3.直接解压该文件 sudo tar -xvf jdk-8u45-li ...

  10. Luogu-4410 [HNOI2009]无归岛

    裸的仙人掌最大独立子集,结果一个zz的错误让我调了好久... \(-inf\)开始设为\(0x7fffffff\)结果\(A_i\)有负数一加就炸了 #include<cstdio> #i ...