【题解】[P4178 Tree]
【题解】P4178 Tree
一道点分治模板好题
不知道是不是我见到的题目太少了,为什么这种题目都是暴力开值域的桶QAQ??
问点对,考虑点分治吧。直接用值域树状数组开下来,统计的时候直接往树状数组里面查询。记得每一层先把这一层的答案统计一下,统计的方法就是刚刚讲的在桶里查。
问题是回溯,值域不大,所以常数还可以,但是我们最好还是开个\(temp\)把我们做修改的地方记录一下,在\(calc\)返回的时候直接回溯。
时间复杂度\(nlog^2n\) 有一些细节需要注意。比如要把\(d[]\)的先统计进去。这一部分答案是从节点到根,没有被点分治覆盖到。
#include<bits/stdc++.h>
using namespace std;
#define RP(t,a,b) for(register int t=(a),edd=(b);t<=edd;++t)
#define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;--t)
#define ERP(t,a) for(register int t=head[a];t;t=e[t].nx)
#define Max(a,b) ((a)<(b)?(b):(a))
#define Min(a,b) ((a)<(b)?(a):(b))
#define midd register int mid=(l+r)>>1
#define TMP template < class ccf >
#define lowbit(x) ((x)&(-x))
TMP inline ccf qr(ccf b){
char c=getchar();
int q=1;
ccf x=0;
while(c<48||c>57)
q=c==45?-1:q,c=getchar();
while(c>=48&&c<=57)
x=x*10+c-48,c=getchar();
return q==-1?-x:x;
}
const int maxn=40000+15;
int n,m;
struct E{
int to,w,nx;
}e[maxn<<1];
int head[maxn];
int cnt;
inline void add(int fr,int to,int w,bool f){
e[++cnt]=(E){to,w,head[fr]};
head[fr]=cnt;
if(f)
add(to,fr,w,0);
}
bool usd[maxn];
int siz[maxn];
int spa[maxn];
int sav[maxn];
int d[maxn];
int rt;
int k;
int data[20005];
int q[maxn];
int sum;
int ans;
inline void add(int x,int qaq){
for(register int t=x+1;t<=20001;t+=lowbit(t))data[t]+=qaq;
}
inline int ask(int x){register int ret=0;
for(register int t=Min(x+1,20001);t>0;t-=lowbit(t))ret+=data[t];
return ret;
}
void dfsroot(int now,int last){
siz[now]=1;
spa[now]=0;
ERP(t,now){
if(e[t].to!=last&&!usd[e[t].to]){
dfsroot(e[t].to,now);
siz[now]+=siz[e[t].to];
spa[now]=Max(spa[now],siz[e[t].to]);
}
}
spa[now]=Max(spa[now],sum-siz[now]);
if(spa[now]<spa[rt]||rt==0)
rt=now;
}
void dfsdis(int now,int last,int ew){
d[now]=d[last]+ew;
sav[++sav[0]]=d[now];
ERP(t,now){
if(e[t].to!=last&&!usd[e[t].to]){
dfsdis(e[t].to,now,e[t].w);
}
}
}
inline void calc(int now){
register int p=0;
ERP(t,now){
if(!usd[e[t].to]){
sav[0]=0;
dfsdis(e[t].to,0,e[t].w);
RP(i,1,sav[0])
ans+=ask(k-sav[i]);
RP(i,1,sav[0])
if(sav[i]<=k) ans++;
RP(i,1,sav[0]) add(sav[i],1);
RP(i,1,sav[0]) q[++p]=sav[i];
}
}
RP(t,1,p)
add(q[t],-1);
}
void solve(int now){
usd[now]=1;
calc(now);
ERP(t,now){
if(!usd[e[t].to]){
sum=siz[e[t].to];
rt=0;
dfsroot(e[t].to,0);
solve(rt);
}
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
n=qr(1);
for(register int t=1,t1,t2,t3;t<n;++t){
t1=qr(1);
t2=qr(1);
t3=qr(1);
add(t1,t2,t3,1);
}
k=qr(1);
sum=n;
dfsroot(1,0);
solve(rt);
cout<<ans<<endl;
return 0;
}
【题解】[P4178 Tree]的更多相关文章
- luogu P4178 Tree
题目链接 luogu P4178 Tree 题解 点分治 代码 // luogu-judger-enable-o2 #include<cstdio> #include<algorit ...
- POJ1471 Tree/洛谷P4178 Tree
Tree P4178 Tree 点分治板子. 点分治就是直接找树的重心进行暴力计算,每次树的深度不会超过子树深度的\(\frac{1}{2}\),计算完就消除影响,找下一个重心. 所以伪代码: voi ...
- [Luogu P4178]Tree 题解(点分治+平衡树)
题目大意 给定一棵树,边带权,问有多少点对满足二者间距离$\leq K$,$n \leq 40000$. 题解 点分治专题首杀!$Jackpot!$ (本来看着题意比较简单想捡个软柿子捏,结果手断了… ...
- [LeetCode 题解]: Binary Tree Preorder Traversal
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Given a bi ...
- [LeetCode 题解]: Symmetric Tree
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Given a ...
- 洛谷P4178 Tree (点分治)
题目描述 给你一棵TREE,以及这棵树上边的距离.问有多少对点它们两者间的距离小于等于K 输入输出格式 输入格式: N(n<=40000) 接下来n-1行边描述管道,按照题目中写的输入 接下 ...
- 竞赛题解 - Broken Tree(CF-758E)
Broken Tree(CF-758E) - 竞赛题解 贪心复习~(好像暴露了什么算法--) 标签:贪心 / DFS / Codeforces 『题意』 给出一棵以1为根的树,每条边有两个值:p-强度 ...
- [题解] 树(tree)
题目大意 给定一颗 \(N\) 个点的有根树,其中 \(1\) 是树根,除了 \(1\) 以外的其他点 \(u\) 有唯一的父亲 \(Father_u\).同时,给定 \(M\) 条路径,第 \( ...
- leetcode题解:Tree Level Order Traversal II (二叉树的层序遍历 2)
题目: Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from ...
随机推荐
- vs2013 x64 编译汇编代码
x64不再支持__asm, 只能单独放在一个.asm中. xxx.asm--------属性 应用 会出现 自定义生成工具. 下面黑体是我们修改的内容.
- 多线程一共就俩问题:1.线程安全(访问共享数据) 2.线程通信(wait(),notify())
多线程一共就俩问题:1.线程安全(访问共享数据) 2.线程通信(wait(),notify()) 1.线程安全,无非就是加锁,访问共享资源时,synchronized 2.线程通信,就是控制各个线程之 ...
- iOS使用MD5 - 字符串加密至MD5&获取文件MD5
iOS 字符串加密至MD5 + (NSString *) md5:(NSString *)str { unsigned ]; CC_MD5( cStr, strlen(cStr), result ); ...
- 对数据进行GZIP压缩和解压
public class GzipUtils { /** * 对字符串进行gzip压缩 * @param data * @return * @throws IOException */ public ...
- Web终端之使用shellinabox在浏览器进行ssh登录
shellinbox有一个内建的web server作为基本的web ssh client,允许你通过指定的端口访问linux服务器的ssh shell,只要你的浏览器支持AJAX/JS/CSS就可以 ...
- 对国外某hotel的内网域简单渗透
Penetration Testing不单单是一个博客,更热衷于技术分享的平台. 本文将讲述对国外某一hotel的渗透测试,让更多的人安全意识得到提高,有攻才有防,防得在好,也有疏忽的地方,这就是为啥 ...
- Mongo JavaTest
import com.mongodb.MongoClient; import com.mongodb.DB; import com.mongodb.DBCollection; import com.m ...
- Java使用笔记之对象比较
1.关于java对象的比较,经常会遇见比较某个两个对象的多个属性是否相等,可以通过重写对象equals方法来实现. 比如有两个User,如果姓名和年龄相等的话,我们就可以认为他们重复的数据.那么我们就 ...
- SQL Server -使用表触发器记录表插入,更新,删除行数
1.如何使用sql获取当前session用户名和机器名 Select CURRENT_USER,Host_name() 2.如何在表触发器中获取当前表名称 SELECT OBJECT_SCHEMA_N ...
- 结构体定义:struct与typedef struct
https://blog.csdn.net/haiou0/article/details/6877718?tdsourcetag=s_pcqq_aiomsg https://blog.csdn.net ...