●CodeForce 293E Close Vertices
题链:
http://codeforces.com/contest/293/problem/E
题解:
点分治,树状数组
大致思路和 POJ 1741 那道点分治入门题相同,
只是因为多了一个路径的边数限制,
所以在统计答案时,
要用数据结构维护一下在满足距离限制的情况下,有多少点也满足边数限制。
树状数组维护到当前的根(重心)的距离为x时的点的个数。
在calc函数中,记录dep[u]表示u到当前的根(重心)的边数,
然后统计u号点可以和多少点组成合法点对时,就查询树状数中有多少点满足到根的距离小于等于W-dep[u].(W是输入的边数限制)
代码:
#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
typedef pair<int,int>pii;
struct EDGE{
int ent;
int to[MAXN*2],nxt[MAXN*2],val[MAXN*2],head[MAXN];
void Reset(){ent=2; memset(head,0,sizeof(head));}
void Adde(int u,int v,int w){
to[ent]=v; val[ent]=w; nxt[ent]=head[u]; head[u]=ent++;
to[ent]=u; val[ent]=w; nxt[ent]=head[v]; head[v]=ent++;
}
}E;
struct BIT{
int val[MAXN],N;
int Lowbit(int x){return x&-x;}
void Reset(int n){
N=n+1; //memset(val,0,sizeof(val));
}
void Modify(int p,int x){
p++; for(;p<=N;p+=Lowbit(p)) val[p]+=x;
}
int Query(int p){
static int ans; ans=0; p++;
for(;p;p-=Lowbit(p)) ans+=val[p];
return ans;
}
}DT;
int N,K,W;
long long ANS;
int size[MAXN];
bool vis[MAXN];
void getroot(int u,int dad,int num,int &root,int &rootnum){
int maxnum=0; size[u]=0;
for(int i=E.head[u];i;i=E.nxt[i]){
if(E.to[i]==dad||vis[E.to[i]]) continue;
getroot(E.to[i],u,num,root,rootnum);
size[u]+=size[E.to[i]];
maxnum=max(maxnum,size[E.to[i]]);
}
size[u]++; maxnum=max(maxnum,num-size[u]);
if(maxnum<rootnum) root=u,rootnum=maxnum;
}
long long calc(int s,int len,int deep){
long long ret=0;
static pii A[MAXN];
static int dis[MAXN],dep[MAXN],reach[MAXN],rnt,ant;
static queue<int>Q;
ant=0; rnt++; Q.push(s);
dis[s]=len; reach[s]=rnt; dep[s]=deep;
while(!Q.empty()){
int u=Q.front(); Q.pop();
A[++ant]=make_pair(dis[u],dep[u]);
for(int i=E.head[u];i;i=E.nxt[i]){
int v=E.to[i];
if(reach[v]==rnt||vis[v]) continue;
dis[v]=dis[u]+E.val[i];
dep[v]=dep[u]+1;
reach[v]=rnt; Q.push(v);
}
}
sort(A+1,A+ant+1);
for(int i=1;i<=ant;i++) DT.Modify(A[i].second,1);
int l=1,r=ant;
while(l<=r){
if(A[l].first+A[r].first>K) DT.Modify(A[r].second,-1),r--;
else DT.Modify(A[l].second,-1),ret+=(W-A[l].second>=0?DT.Query(W-A[l].second):0),l++;
}
return ret;
}
void divide(int u){
int root=u,rootnum=size[u];
getroot(u,0,size[u],root,rootnum);
vis[root]=1;
ANS+=calc(root,0,0);
for(int i=E.head[root];i;i=E.nxt[i]) if(!vis[E.to[i]])
ANS-=calc(E.to[i],E.val[i],1);
for(int i=E.head[root];i;i=E.nxt[i]) if(!vis[E.to[i]])
divide(E.to[i]);
}
void read(int &x){
static int sign; static char ch;
x=0; sign=1; ch=getchar();
while(ch<'0'||'9'<ch){if(ch=='-')sign=-1;ch=getchar();}
while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
x=x*sign;
}
int main(){
read(N); read(W); read(K);
E.Reset(); DT.Reset(N); ANS=0;
for(int i=2,dad,w;i<=N;i++)
read(dad),read(w),E.Adde(dad,i,w);
size[1]=N; divide(1);
cout<<ANS<<endl;
return 0;
}
●CodeForce 293E Close Vertices的更多相关文章
- codeforces 293E Close Vertices
题目链接 正解:点分治+树状数组. 点分治板子题,直接点分以后按照$w$排序,扫指针的时候把$w$合法的路径以$l$为下标加入树状数组统计就行了. 写这道题只是想看看我要写多久..事实证明我确实是老年 ...
- CF 293E Close Vertices——点分治
题目:http://codeforces.com/contest/293/problem/E 仍旧是点分治.用容斥,w的限制用排序+两个指针解决, l 的限制就用树状数组.有0的话就都+1,相对大小不 ...
- CodeForces 293E Close Vertices 点分治
题目传送门 题意:现在有一棵树,每条边的长度都为1,然后有一个权值,求存在多少个(u,v)点对,他们的路劲长度 <= l, 总权重 <= w. 题解: 1.找到树的重心. 2.求出每个点到 ...
- 强连通分量&hdu_1269&Codeforce 369D
强连通分量 标签: 图论 算法介绍 还记得割点割边算法吗.回顾一下,tarjan算法,dfs过程中记录当前点的时间戳,并通过它的子节点的low值更新它的low,low值是这个点不通过它的父亲节点最远可 ...
- Codeforce - Street Lamps
Bahosain is walking in a street of N blocks. Each block is either empty or has one lamp. If there is ...
- Codeforce#331 (Div. 2) A. Wilbur and Swimming Pool(谨以此题来纪念我的愚蠢)
C time limit per test 1 second memory limit per test 256 megabytes input standard input output stand ...
- Codeforce Round #216 Div2
e,还是写一下这次的codeforce吧...庆祝这个月的开始,看自己有能,b到什么样! cf的第二题,脑抽的交了错两次后过了pretest然后system的挂了..脑子里还有自己要挂的感觉,果然回头 ...
- dataStructure@ Find if there is a path between two vertices in a directed graph
Given a Directed Graph and two vertices in it, check whether there is a path from the first given ve ...
- cf293E Close Vertices(树分治+BIT)
E. Close Vertices You've got a weighted tree, consisting of n vertices. Each edge has a non-negative ...
随机推荐
- 释义Oracle 11r2中并行执行相关参数
因最近对现场某些服务器进行诊断和调整,用到了这类参数,因此对这类参数做了详尽的查阅和研究,现将该类参数释义如下,以方便同行和自己参考,禁止转载: 1.PARALLEL_ADAPTIVE_MULTI_U ...
- Lock(三)查看是谁把表给锁了
查看是谁把表给锁了 select se1.inst_id as 被阻塞的会话节点, se2.inst_id as 罪魁祸首节点, se1.sid as 被阻塞的会话ID, ob.object_name ...
- Mego开发文档 - 处理并发冲突
处理并发冲突 数据库并发是指多个进程或用户同时访问或更改数据库中的相同数据的情况.并发控制是指用于确保存在并发更改时数据一致性的特定机制. Mego实现了乐观并发控制,这意味着它可以让多个进程或用户独 ...
- 新概念英语(1-97)A Small Blue Case
Lesson 97 A small blue case 一只蓝色的小箱子 Listen to the tape then answer this question. Does Mr. Hall get ...
- RocketMQ(五):namesrv初探
匠心零度 转载请注明原创出处,谢谢! RocketMQ网络部署图 NameServer:在系统中是做命名服务,更新和发现 broker服务. Broker-Master:broker 消息主机服务器. ...
- 【原生js实现一键回到顶部】
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- 前端学习之jquery
前端学习之jquery 1. 什么是jQuery对象? jQuery对象就是通过jQuery包装DOM对象后产生的对象.jQuery对象是jQuery独有的.如果一个对象是jQuery对象,那么它 ...
- Windows10+Docker搭建分布式Redis集群(SSH服务镜像)(二)
前言:上篇文章我们搭建好了Docker,下面我们开始使用Docker创建镜像,Docker命令就不介绍了.这里宿主是Windows10,cmd的管理和后期文件的复制不是很方便,将创建支持SSH的Cen ...
- Java:Java 中会存在内存泄漏吗
理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是Java被广泛使用于服务器端编程的一个重要原因):然而在实际开发中,可能会存在无用但可达的对象,这些对象不能被GC回收,因此也会导致 ...
- MyBatis(三):数据库查询结果不为空,但是使用MyBatis框架查询为空问题
1.这个问题主要和返回字段是否和实体类javabean中的字段是否一致导致的问题. 解决方案: sql语句 : select account_id as "accountId" a ...