传送门:hdu 5861 Road

题意:

  1. 水平线上n个村子间有 n-1 条路. 每条路开放一天的价格为 Wi
  2. 有 m 天的操作,每天需要用到村子 Ai~Bi 间的道路
  3. 每条路只能开放或关闭一次. (不能重复开关)
  4. 求每天的最小花费.

思路:

  1. 第一次线段树:维护每条路第一次和最后一次被用到的天数.以下代码维护了 mn:第一次被用到,mx:最后一次被用到,lazy:被更新的最大值
    若当前区间被lazy维护而没有更新到点,那么这个子节点的最小值就可能被改变.所以我这里的子节点更新是根据父节点的最大和最小来更新,因为没有pushup操作,所以父节点记录的就是这个区间的最大和最小值。而lazy的作用仅是为了判断是否需要更新子节点,以减少更新操作
  2. 第二次线段树:维护每天用了多少钱.
    根据以上结果维护,对于每条路(被用到过的)区间更新第一次到最后一次这些天用的钱.
/**************************************************************
Problem:hdu 5861 Road
User: youmi
Language: C++
Result: Accepted
Time:2714MS
Memory:23936K
****************************************************************/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <cmath>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d\n",a)
#define ptlld(a) printf("%I64d\n",a)
#define rep(i,from,to) for(int i=from;i<=to;i++)
#define irep(i,to,from) for(int i=to;i>=from;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define eps 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl
const double pi=*atan(1.0); using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
template <class T> inline void read(T &n)
{
char c; int flag = ;
for (c = getchar(); !(c >= '' && c <= '' || c == '-'); c = getchar()); if (c == '-') flag = -, n = ; else n = c - '';
for (c = getchar(); c >= '' && c <= ''; c = getchar()) n = n * + c - ''; n *= flag;
}
ll Pow(ll base, ll n, ll mo)
{
if (n == ) return ;
if (n == ) return base % mo;
ll tmp = Pow(base, n >> , mo);
tmp = (ll)tmp * tmp % mo;
if (n & ) tmp = (ll)tmp * base % mo;
return tmp;
}
//*************************** int n,m;
const int maxn=+;
const ll mod=;
pii p[maxn];
int a[maxn];
ll ans[maxn];
struct tree
{
int l,r;
int mx,mn;
int lz;
tree(){}
tree(int _l,int _r,int _mx,int _mn,int _lz)
{
l=_l,r=_r,mx=_mx,mn=_mn,lz=_lz;
}
}seg[maxn<<];
struct tree1
{
int l,r;
ll val;
tree1(){}
tree1(int _l,int _r,ll _val)
{
l=_l,r=_r,val=_val;
}
}seg1[maxn<<];
void build(int step,int l,int r)
{
seg[step]=tree(l,r,-oo,oo,);
if(l==r)
return;
int mid=(l+r)>>;
build(lson,l,mid);
build(rson,mid+,r);
}
void build1(int step,int l,int r)
{
seg1[step]=tree1(l,r,);
if(l==r)
return;
int mid=(l+r)>>;
build1(lson,l,mid);
build1(rson,mid+,r);
}
void pushdown(int step)
{
seg[lson].mn=min(seg[lson].mn,seg[step].mn);
seg[rson].mn=min(seg[rson].mn,seg[step].mn);
seg[lson].mx=max(seg[lson].mx,seg[step].mx);
seg[rson].mx=max(seg[rson].mx,seg[step].mx);
seg[lson].lz=max(seg[lson].lz,seg[step].lz);
seg[rson].lz=max(seg[rson].lz,seg[step].lz);
seg[step].lz=;
}
void pushdown1(int step)
{
seg1[lson].val+=seg1[step].val;
seg1[rson].val+=seg1[step].val;
seg1[step].val=;
}
void update(int step,int l,int r,int val)
{
if(seg[step].l==l&&seg[step].r==r)
{
seg[step].mx=max(seg[step].mx,val);
seg[step].mn=min(seg[step].mn,val);
seg[step].lz=max(seg[step].lz,val);
return ;
}
if(seg[step].lz)
pushdown(step);
int mid=(seg[step].l+seg[step].r)>>;
if(mid>=r)
update(lson,l,r,val);
else if(mid<l)
update(rson,l,r,val);
else
{
update(lson,l,mid,val);
update(rson,mid+,r,val);
}
}
void update1(int step,int l,int r,int v)
{
if(seg1[step].l==l&&seg1[step].r==r)
{
seg1[step].val+=v;
return ;
}
if(seg1[step].val)
pushdown1(step);
int mid=(seg1[step].l+seg1[step].r)>>;
if(mid>=r)
update1(lson,l,r,v);
else if(mid<l)
update1(rson,l,r,v);
else
{
update1(lson,l,mid,v);
update1(rson,mid+,r,v);
}
}
void query(int step)
{
if(seg[step].l==seg[step].r)
{
p[seg[step].l]=make_pair(seg[step].mn,seg[step].mx);
return ;
}
if(seg[step].lz)
pushdown(step);
query(lson);
query(rson);
}
void query1(int step)
{
if(seg1[step].l==seg1[step].r)
{
ans[seg1[step].l]=seg1[step].val;
return ;
}
if(seg1[step].val)
pushdown1(step);
query1(lson);
query1(rson);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
while(~sc2(n,m))
{
rep(i,,n-)
sc(a[i]);
build(,,n-);
rep(i,,m)
{
int l,r;
sc2(l,r);
if(l>r)
swap(l,r);
update(,l,r-,i);
}
query();
build1(,,m);
rep(i,,n-)
if(p[i].first!=oo&&p[i].second!=-oo)
update1(,p[i].first,p[i].second,a[i]);
query1();
rep(i,,m)
ptlld(ans[i]);
}
}

hdu 5861 Road 两棵线段树的更多相关文章

  1. cf276E 两棵线段树分别维护dfs序和bfs序,好题回头再做

    搞了一晚上,错了,以后回头再来看 /* 对于每次更新,先处理其儿子方向,再处理其父亲方向 处理父亲方向时无法达到根,那么直接更新 如果能达到根,那么到兄弟链中去更新,使用bfs序 最后,查询结点v的结 ...

  2. HDU 5861 Road (线段树)

    Road 题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5861 Description There are n villages alo ...

  3. HDU.5692 Snacks ( DFS序 线段树维护最大值 )

    HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...

  4. UVA - 12424 Answering Queries on a Tree(十棵线段树的树链剖分)

    You are given a tree with N nodes. The tree nodes are numbered from 1 to N and have colors C1, C2,. ...

  5. HDU 2665.Kth number-可持久化线段树(无修改区间第K小)模板 (POJ 2104.K-th Number 、洛谷 P3834 【模板】可持久化线段树 1(主席树)只是输入格式不一样,其他几乎都一样的)

    Kth number Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. HDU 4819:Mosaic(线段树套线段树)

    http://acm.hdu.edu.cn/showproblem.php?pid=4819 题意:给出一个矩阵,然后q个询问,每个询问有a,b,c,代表(a,b)这个点上下左右c/2的矩形区域内的( ...

  7. Codeforces J. A Simple Task(多棵线段树)

    题目描述: Description This task is very simple. Given a string S of length n and q queries each query is ...

  8. R - Weak Pair HDU - 5877 离散化+权值线段树+dfs序 区间种类数

    R - Weak Pair HDU - 5877 离散化+权值线段树 这个题目的初步想法,首先用dfs序建一颗树,然后判断对于每一个节点进行遍历,判断他的子节点和他相乘是不是小于等于k, 这么暴力的算 ...

  9. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

随机推荐

  1. javascript url几种编码方式

    1.escape() 不能直接用于URL编码,它的真正作用是返回一个字符的Unicode编码值.比如“春节”的返回结果是%u6625%u8282,escape()不对"+"编码主要 ...

  2. 如何使用mybatis《二》

    前边阐述了如何在java项目中使用mybatis,我们使用的是映射文件的方式,在获得具体的数据操作方法时需要传入映射文件中namespace+“.”方法名称,这种方式有时候会感觉很不爽,很麻烦.我们在 ...

  3. Mssql链接mysql数据库

    最近在做mysql数据库实时同步到mssql数据库的方案,花了一周时间,测试通过了,在实际机器上测试出现了若干问题.第一个问题就是在mssql上链接mysql的问题. 第一步,安装 Mysql ODB ...

  4. android 数据文件存取至储存卡

    来自:http://blog.csdn.net/jianghuiquan/article/details/8569233 <?xml version="1.0" encodi ...

  5. 如何在树莓派上运行雷神之锤III

    昨天在树莓派上尝试运行了一下雷神之锤III,流畅运行,效果不错~~~ RPI这个小身板的东东总是可以给你带来惊喜,这里记录一下步骤以备后续再用 先确保RPI的程序和固件都已经更新 sudo apt-g ...

  6. 【读书笔记】iOS-对象初始化

    一,分配对象. 分配是一个样的对象诞生的过程.最美好的时刻,是从操作系统获得一块内存并将其指定为存放对象的实例变量的位置.向某个类发送alloc消息的结果,就是为该类分配一块足够大的内存,以存放该内的 ...

  7. 复杂对象的本地化(以Person为例)

    Person.h #import <Foundation/Foundation.h> @interface Person : NSObject <NSCoding> /// 姓 ...

  8. 编译iOS程序时的-all_load选项,以及-all_load 导致的 ld duplicate symbol xx的问题

    在新的SDK环境中调试百度地图的应用程序时,app总是意外退出,找了半天发现错误的原因是unrecognized selector xx的错误,另外还有报了一个Unknown class XXX in ...

  9. iOS开发笔记15:地图坐标转换那些事、block引用循环/weak–strong dance、UICollectionviewLayout及瀑布流、图层混合

    1.地图坐标转换那些事 (1)投影坐标系与地理坐标系 地理坐标系使用三维球面来定义地球上的位置,单位即经纬度.但经纬度无法精确测量距离戒面积,也难以在平面地图戒计算机屏幕上显示数据.通过投影的方式可以 ...

  10. 自学 iOS – 三十天三十个 Swift 项目

    自学 iOS – 三十天三十个 Swift 项目 github源码地址:https://github.com/allenwong/30DaysofSwift