POJ 3162 bit区间查询最值+树形DP
POJ 3162
『题目链接』POJ 3162
『题目类型』bit区间查询最值+树形DP
✡Problem:
一棵n个节点的树。wc爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要在这n个距离里取连续的若干天,使得这些天里最大距离和最小距离的差小于M,问怎么取使得天数最多?
✡Answer:
参考:http://blog.csdn.net/angon823/article/details/52314522
这题和HDU 2196有相同的部分,先求一下树上每个点到其它点的最远距离。问题就转化为:求一个最长的符合要求的区间,即区间里 最大值 - 最小值 < M。
我用的是树状数组初始化和查询最值,当然也可以用线段树;可以求区间最值了,那么我们用尺取法就可以求出最长的区间了:维护两个指针i,j;让i=j=1;先右移j,直到不符合情况时再右移i,之后每次更新最大长度就好了。
fread输入挂能省1s
我看了看数据,1e6,就想弄弄输入挂试试,结果如下,上面的是输入挂。fread真的牛逼,但一定不要忘了要在main函数中加2句:fread(Buf, 1, BUF, stdin); fwrite(Out, 1, ou - Out, stdout);
如果不加第一句,输入时就会rt;如果不加第二句,就没有输出。
『时间复杂度』\(O(nlogn)\)
✡Code:
#include <map>
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <set>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define cle(a,v) memset(a,(v),sizeof(a))
#define fo(i,a,b) for(int i=(a);i<=(b);i++)
#define fd(i,a,b) for(int i=(a);i>=(b);i--)
#define ll long long
const int maxn = 1e6 + 7;
int n, m, u, v, w, tot, head[maxn], dp[maxn][3], num[maxn];
struct Edge {
int v, w, next;
} edges[maxn << 1];
void added(int u, int v, int w) {
edges[tot] = Edge{v, w, head[u]};
head[u] = tot++;
}
void init() {
tot = 0;
cle(head, -1);
}
void dfsson(int u, int fa) {
for (int i = head[u]; ~i; i = edges[i].next) {
int v = edges[i].v;
if (v == fa) continue;
dfsson(v, u);
int temporary = dp[v][0] + edges[i].w;
if (temporary >= dp[u][0]) {
dp[u][1] = dp[u][0];
dp[u][0] = temporary;
}
else if (temporary > dp[u][1]) {
dp[u][1] = temporary;
}
}
}
void dfsfa(int u, int fa) {
for (int i = head[u]; ~i; i = edges[i].next) {
int v = edges[i].v;
if (v == fa) continue;
if (dp[u][0] == dp[v][0] + edges[i].w) {
dp[v][2] = max(dp[u][2], dp[u][1]) + edges[i].w;
}
else {
dp[v][2] = max(dp[u][2], dp[u][0]) + edges[i].w;
}
dfsfa(v, u);
}
}
#define lowb(x) (x&-x)
struct node {
int ma, mi;
} bit[maxn];
void Binit() {
for (int i = 1; i <= n; i++) {
bit[i].ma = num[i];
bit[i].mi = num[i];
for (int j = 1; j < lowb(i); j <<= 1) {
bit[i].ma = max(bit[i].ma, bit[i - j].ma);
bit[i].mi = min(bit[i].mi, bit[i - j].mi);
}
}
}
node Bquery(int l, int r) {
node ans = node{num[r], num[r]};
while (true) {
ans.ma = max(ans.ma, num[r]);
ans.mi = min(ans.mi, num[r]);
if (r == l) break;
for (r--; r - l >= lowb(r); r -= lowb(r)) {
ans.ma = max(ans.ma, bit[r].ma);
ans.mi = min(ans.mi, bit[r].mi);
}
}
return ans;
}
int main() {
freopen("1.in", "r", stdin);
init();
scanf("%d%d", &n, &m);
for (int i = 2; i <= n; i++) {
scanf("%d%d", &v, &w);
added(i, v, w); added(v, i, w);
}
dfsson(1, -1);
dfsfa(1, -1);
for (int i = 1; i <= n; i++)
num[i] = max(dp[i][0], dp[i][2]);
// fo(i, 1, n) {
// printf("%d ", num[i]);
// } printf("\n");
Binit();
int len = 1, i = 1, j = 1;
while (j <= n) {
node a = Bquery(i, j);
while (a.ma - a.mi < m && j <= n) {
j++;
a = Bquery(i, j);
}
len = max(len, j - i);
i++;
}
printf("%d\n", len);
return 0;
}
✡Code_fread():
#include <map>
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <set>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define cle(a,v) memset(a,(v),sizeof(a))
#define fo(i,a,b) for(int i=(a);i<=(b);i++)
#define fd(i,a,b) for(int i=(a);i>=(b);i--)
#define ll long long
const int maxn = 1e6 + 7;
int n, m, u, v, w, tot, head[maxn], dp[maxn][3], num[maxn];
struct Edge {
int v, w, next;
} edges[maxn << 1];
void added(int u, int v, int w) {
edges[tot] = Edge{v, w, head[u]};
head[u] = tot++;
}
void init() {
tot = 0;
cle(head, -1);
}
void dfsson(int u, int fa) {
for (int i = head[u]; ~i; i = edges[i].next) {
int v = edges[i].v;
if (v == fa) continue;
dfsson(v, u);
int temporary = dp[v][0] + edges[i].w;
if (temporary >= dp[u][0]) {
dp[u][1] = dp[u][0];
dp[u][0] = temporary;
}
else if (temporary > dp[u][1]) {
dp[u][1] = temporary;
}
}
}
void dfsfa(int u, int fa) {
for (int i = head[u]; ~i; i = edges[i].next) {
int v = edges[i].v;
if (v == fa) continue;
if (dp[u][0] == dp[v][0] + edges[i].w) {
dp[v][2] = max(dp[u][2], dp[u][1]) + edges[i].w;
}
else {
dp[v][2] = max(dp[u][2], dp[u][0]) + edges[i].w;
}
dfsfa(v, u);
}
}
#define lowb(x) (x&-x)
struct node {
int ma, mi;
} bit[maxn];
void Binit() {
for (int i = 1; i <= n; i++) {
bit[i].ma = num[i];
bit[i].mi = num[i];
for (int j = 1; j < lowb(i); j <<= 1) {
bit[i].ma = max(bit[i].ma, bit[i - j].ma);
bit[i].mi = min(bit[i].mi, bit[i - j].mi);
}
}
}
node Bquery(int l, int r) {
node ans = node{num[r], num[r]};
while (true) {
ans.ma = max(ans.ma, num[r]);
ans.mi = min(ans.mi, num[r]);
if (r == l) break;
for (r--; r - l >= lowb(r); r -= lowb(r)) {
ans.ma = max(ans.ma, bit[r].ma);
ans.mi = min(ans.mi, bit[r].mi);
}
}
return ans;
}
const int BUF = 40000000;
char Buf[BUF], *buf = Buf;
const int OUT = 20000000;
char Out[OUT], *ou = Out; int Outn[30], Outcnt;
inline void write(int x) {
if (!x)*ou++ = 48;
else {
for (Outcnt = 0; x; x /= 10)Outn[++Outcnt] = x % 10 + 48;
while (Outcnt)*ou++ = Outn[Outcnt--];
}
}
inline void writell(ll x) {
if (!x)*ou++ = 48;
else {
for (Outcnt = 0; x; x /= 10)Outn[++Outcnt] = x % 10 + 48;
while (Outcnt)*ou++ = Outn[Outcnt--];
}
}
inline void writechar(char x) {*ou++ = x;}
inline void writeln() {*ou++ = '\n';}
inline void read(int&a) {for (a = 0; *buf < 48; buf++); while (*buf > 47)a = a * 10 + *buf++ -48;}
int main() {
freopen("1.in", "r", stdin);
init();
//DON'T FOGET THIS!!!
fread(Buf, 1, BUF, stdin);
read(n), read(m);
for (int i = 2; i <= n; i++) {
read(v), read(w);
added(i, v, w); added(v, i, w);
}
dfsson(1, -1);
dfsfa(1, -1);
for (int i = 1; i <= n; i++)
num[i] = max(dp[i][0], dp[i][2]);
// fo(i, 1, n) {
// printf("%d ", num[i]);
// } printf("\n");
Binit();
int len = 1, i = 1, j = 1;
while (j <= n) {
node a = Bquery(i, j);
while (a.ma - a.mi < m && j <= n) {
j++;
a = Bquery(i, j);
}
len = max(len, j - i);
i++;
}
write(len);
writeln();
//DON'T FOGET THIS!!!
fwrite(Out, 1, ou - Out, stdout);
return 0;
}
POJ 3162 bit区间查询最值+树形DP的更多相关文章
- NOIP2011pj表达式的值[树形DP 笛卡尔树 | 栈 表达式解析]
题目描述 对于1 位二进制变量定义两种运算: 运算的优先级是: 先计算括号内的,再计算括号外的. “× ”运算优先于“⊕”运算,即计算表达式时,先计算× 运算,再计算⊕运算.例如:计算表达式A⊕B × ...
- POJ 2342 &&HDU 1520 Anniversary party 树形DP 水题
一个公司的职员是分级制度的,所有员工刚好是一个树形结构,现在公司要举办一个聚会,邀请部分职员来参加. 要求: 1.为了聚会有趣,若邀请了一个职员,则该职员的直接上级(即父节点)和直接下级(即儿子节点) ...
- 洛谷P1351 联合权值(树形dp)
题意 题目链接 Sol 一道很简单的树形dp,然而被我写的这么长 分别记录下距离为\(1/2\)的点数,权值和,最大值.以及相邻儿子之间的贡献. 树形dp一波.. #include<bits/s ...
- 洛谷 P1351 联合权值 —— 树形DP
题目:https://www.luogu.org/problemnew/show/P1351 树形DP,别忘了子树之间的情况(拐一下距离为2). 代码如下: #include<iostream& ...
- POJ - 2057 The Lost House(树形DP+贪心)
https://vjudge.net/problem/POJ-2057 题意 有一只蜗牛爬上某个树枝末睡着之后从树上掉下来,发现后面的"房子"却丢在了树上面,.现在这只蜗牛要求寻找 ...
- poj 2342 【Anniversary party】树形dp
题目传送门//res tp poj 题意 给出一棵有权树,求一个节点集的权值和,满足集合内的任意两点不存在边 分析 每个点有选中与不选中两种状态,对于第\(i\)个点,记选中为\(sel_i\),不选 ...
- POJ 1849 Two(树的直径--树形DP)(好题)
大致题意:在某个点派出两个点去遍历全部的边,花费为边的权值,求最少的花费 思路:这题关键好在这个模型和最长路模型之间的转换.能够转换得到,全部边遍历了两遍的总花费减去最长路的花费就是本题的答案,要思考 ...
- poj 1694 An Old Stone Game 树形dp
//poj 1694 //sep9 #include <iostream> #include <algorithm> using namespace std; const in ...
- POJ题目1947 Rebuilding Roads(树形dp)
Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 9957 Accepted: 4537 ...
随机推荐
- 这里主要展示在Win7下怎么用IIS发布局域网站
首先对IIS做一个简要的介绍: IIS(InternetInformationServices)互联网信息服务的简称.本质是一种Web(网页)服务组件,其中包含Web.FTP和SMTP三大服务器,分别 ...
- SA:利用SA算法解决TSP(数据是14个虚拟城市的横纵坐标)问题——Jason niu
%SA:利用SA算法解决TSP(数据是14个虚拟城市的横纵坐标)问题——Jason niu X = [16.4700 96.1000 16.4700 94.4400 20.0900 92.5400 2 ...
- Linux 添加到环境变量
在Linux下使用源码安装软件的时候,通常只能在软件安装目录下使用该软件命令,这样太麻烦,我们希望全局使用,可以将软件安装路径添加到系统环境变量里. 添加环境变量有2种方法: 1. 使用export命 ...
- 模拟select,隐藏下拉列表的几种实现
前言 平时开发过程中,出于各种原因模拟原生slect的要求并不算少见. 在实现的过程中,点击其他区域隐藏下拉列表,又是一个必备的功能, 最近在一次开发的过程中引发了点思考,做下总结. 现象 实际中的实 ...
- C# 错误集锦
①字段重复 js → qs 仔细 ② 代码臃肿 通过判断 资产类型zc_type来判断模块的显隐 实际在其中嵌入 <%=zc_type == "2"?"" ...
- Android SQL数据库应用实践 “问题点”“疑难点”“解析”
应用 Android SQL 数据库时,遇到的问题: 场景1:Android SQL查询后,获取到Cursor并查询数据:遇到以下问题:"android.database.CursorInd ...
- Mybatis与JDBC批量插入MySQL数据库性能测试及解决方案
转自http://www.cnblogs.com/fnz0/p/5713102.html 不知道自己什么时候才有这种钻研精神- -. 1 背景 系统中需要批量生成单据数据到数据库表,所以采用 ...
- 转 MYSQL InnoDB Record, Gap, and Next-Key Locks
http://dev.mysql.com/doc/refman/5.0/en/innodb-record-level-locks.html InnoDB has several types of re ...
- javaweb中的文件上传的一般写法(初次接触时写)
javaweb上传文件 上传文件的jsp中的部分 上传文件同样可以使用form表单向后端发请求,也可以使用 ajax向后端发请求 1. 通过form表单向后端发送请求 <form id=&quo ...
- Android常用的工具类SharedPreferences封装类SPUtils
package com.zhy.utils; import java.lang.reflect.InvocationTargetException; import java.lang.reflect. ...