POJ1741Tree [点分治]【学习笔记】
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 20098 | Accepted: 6608 |
Description
Define dist(u,v)=The min distance between node u and v.
Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k.
Write a program that will count how many pairs which are valid for a given tree.
Input
The last test case is followed by two zeros.
Output
题意:给一颗带权树,求树上长度不超过L的路径条数
对于一条树路径 只有经过或不经过一个点的情况
考虑经过一个点的路径,可以由其他点到它的两条路径拼出来
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=,INF=1e9+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,L,u,v,w;
struct edge{
int v,w,ne;
}e[N<<];
int h[N],cnt;
inline void ins(int u,int v,int w){
cnt++;
e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].w=w;e[cnt].ne=h[v];h[v]=cnt;
} int size[N],d[N],vis[N],root,sum;
void dfsRoot(int u,int fa){
size[u]=;d[u]=;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(vis[v]||v==fa) continue;
dfsRoot(v,u);
size[u]+=size[v];
d[u]=max(d[u],size[v]);
}
d[u]=max(d[u],sum-size[u]);
if(d[u]<d[root]) root=u;
}
int deep[N],a[N];
void dfsDeep(int u,int fa){
a[++a[]]=deep[u];
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(vis[v]||v==fa) continue;
deep[v]=deep[u]+e[i].w;
dfsDeep(v,u);
}
} int cal(int u,int now){
deep[u]=now;a[]=;
dfsDeep(u,);
sort(a+,a++a[]);
int l=,r=a[],ans=;
while(l<r){
if(a[l]+a[r]<=L) ans+=r-l,l++;
else r--;
}
return ans;
}
int ans;
void dfsSol(int u){//printf("dfs %d\n",u);
vis[u]=;
ans+=cal(u,);
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(vis[v]) continue;
ans-=cal(v,e[i].w);
sum=size[v];
root=;dfsRoot(v,);
dfsSol(root);
}
} int main(){
//freopen("in.txt","r",stdin);
while(true){
n=read();L=read();if(n==) break;
cnt=;memset(h,,sizeof(h));
memset(vis,,sizeof(vis));
ans=;
for(int i=;i<=n-;i++) u=read(),v=read(),w=read(),ins(u,v,w);
sum=n;
root=;d[]=INF;
dfsRoot(,);
dfsSol(root);
printf("%d\n",ans);
}
}
//
// main.cpp
// treap
//
// Created by Candy on 2017/1/9.
// Copyright ? 2017年 Candy. All rights reserved.
// #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define lc t[x].l
#define rc t[x].r
const int N=1e5+,INF=1e9;
int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
} struct node{
int l,r,v,w,size,rnd;
}t[N];
int sz,root;
inline void update(int x){t[x].size=t[lc].size+t[rc].size+t[x].w;}
inline void lturn(int &x){
int c=rc;rc=t[c].l;t[c].l=x;
t[c].size=t[x].size;update(x);x=c;
}
inline void rturn(int &x){
int c=lc;lc=t[c].r;t[c].r=x;
t[c].size=t[x].size;update(x);x=c;
}
void ins(int &x,int v){
if(x==){
x=++sz;
t[x].l=t[x].r=;
t[x].v=v;t[x].w=t[x].size=;
t[x].rnd=rand();
return;
}
t[x].size++;
if(v==t[x].v) t[x].w++;
else if(v<t[x].v){
ins(lc,v);
if(t[lc].rnd<t[x].rnd) rturn(x);
}else{
ins(rc,v);
if(t[rc].rnd<t[x].rnd) lturn(x);
}
}
int que(int x,int v){//cnt of <v
if(!x) return ;
if(t[x].v==v) return t[lc].size;
if(v<t[x].v) return que(lc,v);
else return t[lc].size+t[x].w+que(rc,v);
} int n,L,u,v,w;
struct edge{
int v,w,ne;
}e[N<<];
int h[N],cnt;
inline void ins(int u,int v,int w){
cnt++;
e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].w=w;e[cnt].ne=h[v];h[v]=cnt;
}
int vis[N],size[N],f[N],sum,rt;
void dfsRoot(int u,int fa){
size[u]=;f[u]=;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(vis[v]||v==fa) continue;
dfsRoot(v,u);
size[u]+=size[v];
f[u]=max(f[u],size[v]);
}
f[u]=max(f[u],sum-size[u]);
if(f[u]<f[rt]) rt=u;
} int ans,deep[N];
void dfsDeep(int u,int fa,int p){
if(p==) ans+=que(root,L-deep[u]+);
else ins(root,deep[u]);
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(vis[v]||v==fa) continue;
deep[v]=deep[u]+e[i].w;
dfsDeep(v,u,p);
}
}
void dfsSol(int u){//printf("sol %d\n",u);
vis[u]=;
sz=root=;
ins(root,);
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(vis[v]) continue;
deep[v]=e[i].w;
dfsDeep(v,u,);
dfsDeep(v,u,);
}
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(vis[v]) continue;
sum=size[v];
rt=;dfsRoot(v,u);
dfsSol(rt);
}
}
int main(){
//freopen("in.txt","r",stdin);
while(true){
n=read();L=read();if(n==) break;
cnt=;memset(h,,sizeof(h));
memset(vis,,sizeof(vis));
ans=;
for(int i=;i<=n-;i++) u=read(),v=read(),w=read(),ins(u,v,w);
sum=n;
rt=;f[]=INF;
dfsRoot(,);
dfsSol(rt);
printf("%d\n",ans);
}
}
POJ1741Tree [点分治]【学习笔记】的更多相关文章
- 点分治&&动态点分治学习笔记
突然发现网上关于点分和动态点分的教程好像很少……蒟蒻开篇blog记录一下吧……因为这是个大傻逼,可能有很多地方写错,欢迎在下面提出 参考文献:https://www.cnblogs.com/LadyL ...
- 初学cdq分治学习笔记(可能有第二次的学习笔记)
前言骚话 本人蒟蒻,一开始看到模板题就非常的懵逼,链接,学到后面就越来越清楚了. 吐槽,cdq,超短裙分治....(尴尬) 正片开始 思想 和普通的分治,还是分而治之,但是有一点不一样的是一般的分治在 ...
- CDQ分治学习笔记
数据结构中的一块内容:$CDQ$分治算法. $CDQ$显然是一个人的名字,陈丹琪(NOI2008金牌女选手) 这种离线分治算法被算法界称为"cdq分治" 我们知道,一个动态的问题一 ...
- [摸鱼]cdq分治 && 学习笔记
待我玩会游戏整理下思绪(分明是想摸鱼 cdq分治是一种用于降维和处理对不同子区间有贡献的离线分治算法 对于常见的操作查询题目而言,时间总是有序的,而cdq分治则是耗费\(O(logq)\)的代价使动态 ...
- CDQ分治学习笔记(三维偏序题解)
首先肯定是要膜拜CDQ大佬的. 题目背景 这是一道模板题 可以使用bitset,CDQ分治,K-DTree等方式解决. 题目描述 有 nn 个元素,第 ii 个元素有 a_iai.b_ibi.c_ ...
- [Updating]点分治学习笔记
Upd \(2020/2/15\),又补了一题 LuoguP2664 树上游戏 \(2020/2/14\),补了一道例题 LuoguP3085 [USACO13OPEN]阴和阳Yin and Yang ...
- 三维偏序[cdq分治学习笔记]
三维偏序 就是让第一维有序 然后归并+树状数组求两维 cdq+cdq不会 告辞 #include <bits/stdc++.h> // #define int long long #def ...
- 学习笔记 | CDQ分治
目录 前言 啥是CDQ啊(它的基本思想) 例题 后记 参考博文 前言 博主太菜了 学习快一年的OI了 好像没有什么会的算法 更寒碜的是 学一样还不精一样TAT 如有什么错误请各位路过的大佬指出啊感谢! ...
- 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)
再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ...
- [学习笔记] 多项式与快速傅里叶变换(FFT)基础
引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积, 而代码量却非常小. 博主一年半前曾经因COGS的一 ...
随机推荐
- 打开redis和solr
- md5加密以及可逆的加密解密算法
md5加密 package gov.mof.fasp2.gcfr.adjustoffset.adjust; import java.security.MessageDigest; public cla ...
- slice、splice与split傻傻分不清
每每看到这几个,就蒙圈了,这都是啥呀? 既然这么容易混淆,我还是来做个小笔记吧,以便日后查阅: 1.slice(数组) 定义:slice() 方法可从已有的数组中返回选定的元素. 用法:array ...
- 从零开始学习前端开发 — 7、CSS宽高自适应
一.宽度自适应 语法:width:100%; 注: a)块状元素的默认宽度为100% b) 当给元素设置宽度为100%时,继承父元素的宽度 c) 通常使用宽度自适应实现通栏效果 二.高度自适应 语法: ...
- ZooKeeper 分布式共享锁的实现
原创播客,如需转载请注明出处.原文地址:http://www.cnblogs.com/crawl/p/8352919.html ------------------------------------ ...
- ThinkPHP3.2 实现Mysql数据库备份
<?php header("Content-type:text/html;charset=utf-8"); //配置信息 $cfg_dbhost = 'localhost'; ...
- 什么是A记录/CNAME记录/MX记录/TXT记录
答: A 记录(Address)是用来指定主机名(或域名)对应的IP地址记录.当你输入域名的时候给你引导向设置在DNS的A记录所对应的服务器. CNAME记录 ( Canonical Name )是一 ...
- Redis在Php项目中的实际应用场景
前言 一些案例中有的同学说为什么不可以用string类型,string类型完全可以实现呀 我建议你看下我的专栏文章<Redis高级用法>,里面介绍了用hash类型的好处 商品维度计数 对商 ...
- Python3 的函数(2)
1.形参和实参 def MyFun(x): return x ** 3 y = 3 print(MyFun(y)) x为形参,y为实参. 2.函数文档 在函数内用单引号引起来的一段文字,在调用函数时不 ...
- Struts2获取Session的三种方式
1.Map<String,Object> session = ActionContext.getContext().getSession(); session.put("cod ...