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的更多相关文章

  1. NOIP2011pj表达式的值[树形DP 笛卡尔树 | 栈 表达式解析]

    题目描述 对于1 位二进制变量定义两种运算: 运算的优先级是: 先计算括号内的,再计算括号外的. “× ”运算优先于“⊕”运算,即计算表达式时,先计算× 运算,再计算⊕运算.例如:计算表达式A⊕B × ...

  2. POJ 2342 &&HDU 1520 Anniversary party 树形DP 水题

    一个公司的职员是分级制度的,所有员工刚好是一个树形结构,现在公司要举办一个聚会,邀请部分职员来参加. 要求: 1.为了聚会有趣,若邀请了一个职员,则该职员的直接上级(即父节点)和直接下级(即儿子节点) ...

  3. 洛谷P1351 联合权值(树形dp)

    题意 题目链接 Sol 一道很简单的树形dp,然而被我写的这么长 分别记录下距离为\(1/2\)的点数,权值和,最大值.以及相邻儿子之间的贡献. 树形dp一波.. #include<bits/s ...

  4. 洛谷 P1351 联合权值 —— 树形DP

    题目:https://www.luogu.org/problemnew/show/P1351 树形DP,别忘了子树之间的情况(拐一下距离为2). 代码如下: #include<iostream& ...

  5. POJ - 2057 The Lost House(树形DP+贪心)

    https://vjudge.net/problem/POJ-2057 题意 有一只蜗牛爬上某个树枝末睡着之后从树上掉下来,发现后面的"房子"却丢在了树上面,.现在这只蜗牛要求寻找 ...

  6. poj 2342 【Anniversary party】树形dp

    题目传送门//res tp poj 题意 给出一棵有权树,求一个节点集的权值和,满足集合内的任意两点不存在边 分析 每个点有选中与不选中两种状态,对于第\(i\)个点,记选中为\(sel_i\),不选 ...

  7. POJ 1849 Two(树的直径--树形DP)(好题)

    大致题意:在某个点派出两个点去遍历全部的边,花费为边的权值,求最少的花费 思路:这题关键好在这个模型和最长路模型之间的转换.能够转换得到,全部边遍历了两遍的总花费减去最长路的花费就是本题的答案,要思考 ...

  8. poj 1694 An Old Stone Game 树形dp

    //poj 1694 //sep9 #include <iostream> #include <algorithm> using namespace std; const in ...

  9. POJ题目1947 Rebuilding Roads(树形dp)

    Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 9957   Accepted: 4537 ...

随机推荐

  1. SQL 性能优化 总结

    SQL 性能优化 总结 (1)选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving ...

  2. Classy Numbers

    http://codeforces.com/group/w1oiqifZbS/contest/1036/problem/C ①先查找,存入vector(dfs)-->排序(sort)--> ...

  3. JS浅谈原始值与引用值操作

    值的操作分为三大类:复制,传递,比较 一:复制 原始值 let a = 10; let b = a; 注释:2018-7-30 17:33:49 1 原始类型的值都是存放在栈内存当中,所以他们的赋值操 ...

  4. [nodemon] clean exit - waiting for changes before restart

    出现上述日志信息,程序就不能往下运行了. 原因:node程序在初始化的时候就报错了,仔细debug吧...

  5. Mysql SQL执行错误:#1136

    情况:在插入数据时可能会遇到这种情况: 原因: 插入时的数据个数与表中的字段个数不一致 解决方法: 检查表中的字段数与代码中所插入的数据字段数是否一致 例如:以下为Salary表中结构  虽然ActI ...

  6. VB中Winsock连续发送出现接收不到的异常问题解决方法

    VB里面用WINSOCK进行一对多连接的TCP连接时,经常需要群发消息给所有已连接的客户端.代码类似如下: Option Explicit Dim bytMsg() As Byte Private S ...

  7. iniReader,读取配置文件中数据

    #include ”IniOperation.h" CString strPath = strIntancePath + _T("..\\config.ini"); // ...

  8. Jedis自己整理比较全的API

    package com.tebon.ams.utils; import com.alibaba.fastjson.JSON;import com.tebon.ams.util.ObjectUtil;i ...

  9. Windows下搭建kafka运行环境

    完整解决方案请参考: Setting Up and Running Apache Kafka on Windows OS   在环境搭建过程中遇到两个问题,在这里先列出来,以方便查询: 1. \Jav ...

  10. ST表 || RMQ问题 || BZOJ 1699: [Usaco2007 Jan]Balanced Lineup排队 || Luogu P2880 [USACO07JAN]平衡的阵容Balanced Lineup

    题面:P2880 [USACO07JAN]平衡的阵容Balanced Lineup 题解: ST表板子 代码: #include<cstdio> #include<cstring&g ...