题意



分析

不难发现把增加人数看成减少人数,上限是w 看成总数是w,问题就变成了询问有多少个子区间没有0。

考虑这个问题困难在哪里,就是区间加减法让我们不好判断0 的位置。

因为题目保证每个位置的值非负,所以实际上我们只需要对于每个区间维护不包含其最小值的子区间的个数。

于是用线段树来维护,每个节点维护区间左边开始第一次出现最小值的位置(到左端的长度),右边开始第一次出现最小值的位置(到右端的长度),最小值的值,区间长度,以及有多少个子区间不包含其最小值即可。

合并的话,分类讨论最小值在哪个区间,然后用上述信息就可以完成合并了。

复杂度为\(O(n +m \log n)\)。

代码

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#pragma GCC optimize ("O0")
using namespace std;
template<class T> inline T read(T&x)
{
T data=0;
int w=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
data=10*data+ch-'0',ch=getchar();
return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff; const int MAXN=3e5+7; int n,m,w[MAXN]; struct node
{
ll ans;
ll lmin,rmin,minv,len; inline node operator+(const node&rhs)const
{
node ret;
ret.len=len+rhs.len;
if(minv==rhs.minv)
{
ret.minv=minv;
ret.lmin=lmin,ret.rmin=rhs.rmin;
ret.ans=ans+rhs.ans+(rmin-1)*(rhs.lmin-1);
}
else if(minv<rhs.minv)
{
ret.minv=minv;
ret.lmin=lmin,ret.rmin=rmin+rhs.len;
ret.ans=ans+rhs.len*(rhs.len+1)/2+(rmin-1)*rhs.len;
}
else
{
ret.minv=rhs.minv;
ret.lmin=rhs.lmin+len,ret.rmin=rhs.rmin;
ret.ans=rhs.ans+len*(len+1)/2+(rhs.lmin-1)*len;
}
return ret;
}
}seg[MAXN<<2]; ll tag[MAXN<<2]; #define lson (now<<1)
#define rson (now<<1|1) void build(int now,int l,int r)
{
tag[now]=0;
if(l==r)
{
seg[now].ans=0;
seg[now].lmin=seg[now].rmin=1;
seg[now].minv=w[l];
seg[now].len=1;
return;
}
int mid=(l+r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
seg[now]=seg[lson]+seg[rson];
} inline void pushdown(int now)
{
if(tag[now])
{
seg[lson].minv+=tag[now],
tag[lson]+=tag[now];
seg[rson].minv+=tag[now],
tag[rson]+=tag[now];
tag[now]=0;
}
} int ql,qr,v; void add(int now,int l,int r)
{
if(ql<=l&&r<=qr)
{
seg[now].minv+=v,
tag[now]+=v;
return;
}
pushdown(now);
int mid=(l+r)>>1;
if(ql<=mid)
add(lson,l,mid);
if(qr>=mid+1)
add(rson,mid+1,r);
seg[now]=seg[lson]+seg[rson];
} node query(int now,int l,int r)
{
if(ql<=l&&r<=qr)
{
return seg[now];
}
pushdown(now);
int mid=(l+r)>>1;
if(qr<=mid)
return query(lson,l,mid);
if(ql>=mid+1)
return query(rson,mid+1,r);
return query(lson,l,mid)+query(rson,mid+1,r);
} int main()
{
freopen("hotel.in","r",stdin);
freopen("hotel.out","w",stdout);
read(n);read(m);
for(int i=1;i<=n;++i)
read(w[i]);
build(1,1,n);
while(m--)
{
int opt;
read(opt);
if(opt==1)
{
read(ql);read(qr);read(v);
v=-v;
add(1,1,n);
}
else
{
read(ql);read(qr);
node ans=query(1,1,n);
if(ans.minv)
printf("%lld\n",ans.len*(ans.len+1)/2);
else
printf("%lld\n",ans.ans);
}
}
// fclose(stdin);
// fclose(stdout);
return 0;
}

test20180919 选择客栈的更多相关文章

  1. NOIP2011选择客栈[递推]

    题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均 ...

  2. 选择客栈noip2011

    哈,没想到吧.今天居然有两篇(算什么,厕所读物吗 选择客栈 本题的更优解请跳转zt 这题11年,刚改2day. 对于30% 的数据,有 n ≤100: 对于50% 的数据,有 n ≤1,000: 对于 ...

  3. 一本通1546【NOIP2011】选择客栈

    1546:NOIP2011 选择客栈 时间限制: 1000 ms         内存限制: 524288 KB 题目描述 丽江河边有 n 家很有特色的客栈,客栈按照其位置顺序从 1 到 n 编号. ...

  4. 洛谷 P1311 选择客栈 解题报告

    P1311 选择客栈 题目描述 丽江河边有 \(n\) 家很有特色的客栈,客栈按照其位置顺序从 \(1\) 到 \(n\) 编号.每家客栈都按照某一种色调进行装饰(总共 \(k\) 种,用整数 \(0 ...

  5. 洛谷P1311 选择客栈

    P1311 选择客栈 题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一 ...

  6. 【11NOIP提高组】选择客栈(信息学奥赛一本通 1546)(洛谷 1311)

    题目描述 丽江河边有nn家很有特色的客栈,客栈按照其位置顺序从 11到nn编号.每家客栈都按照某一种色调进行装饰(总共 kk 种,用整数 00 ~k-1k−1 表示),且每家客栈都设有一家咖啡店,每家 ...

  7. Noip2011 提高组 选择客栈

    P1311 选择客栈 直通 思路: ①看题,我们可以发现一个显然的性质,即当最左边的客栈向右移动时,最右边的客栈时单调向右的,并且右端点往右的客栈也符合要求.(因为只要左侧有一个满足的,右边的自然可以 ...

  8. 【五一qbxt】day7-2 选择客栈

    停更20天祭qwq(因为去准备推荐生考试了一直在自习qwq) [noip2011选择客栈] 这道题的前置知识是DP,可以参考=>[五一qbxt]day3 动态规划 鬼知道我写的是什么emm 这道 ...

  9. luoguP1311 选择客栈 题解(NOIP2011)

    P1311 选择客栈  题目 #include<iostream> #include<cstdlib> #include<cstdio> #include<c ...

随机推荐

  1. memcached 内存初始化与key-value存储

    本次笔记未涉及到slab的动态重新平衡分配 /**首先介绍一下一个跟内存相关的非常重要的概念,内存块类型数据结构:*/ typedef struct { unsigned int size; /* c ...

  2. python-day20--collections模块

    1.namedtuple: 生成可以使用名字来访问元素内容的tuple >>> from collections import namedtuple >>> Poi ...

  3. thinkphp得到客户端的ip

    /** * 获取客户端IP地址 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @return mixed */function get_cli ...

  4. python 爬虫之为什么使用opener对象以及为什么要创建全局默认的opener对象

    基本的urlopen()函数不支持验证.cookie或其他HTTP高级功能.要支持这些功能,必须使用build_opener()函数来创建自己的自定义Opener对象. install_opener( ...

  5. 这可能是最简明扼要的 js事件冒泡机制+阻止默认事件 讲解了

    哎 js事件冒泡机制和阻止冒泡 阻止默认行为好像永远也整不清楚,记了忘 忘了记...醉了 这篇文章写完以后下次再忘记 就呼自己一巴掌,忘一次一巴掌 首先要明白两个概念——事件和事件流 事件指的是用户或 ...

  6. Openwrt Export Gpio Configure (7)

    1      Scope of Document This document describes how to export gpio interface under gpio-export driv ...

  7. CF 463A && 463B 贪心 && 463C 霍夫曼树 && 463D 树形dp && 463E 线段树

    http://codeforces.com/contest/462 A:Appleman and Easy Task 要求是否全部的字符都挨着偶数个'o' #include <cstdio> ...

  8. docker小demo

    http://www.blogjava.net/yongboy/archive/2013/12/12/407498.html

  9. Mysql 中Left/Right join on后面and和where条件查询的差异-Mysql SQL运算符是有优先级

    一.Mysql中Left/Right join on后面and和where条件查询的差异 1.建两张测试表,一张商户定义表.一张商户操作状态明细表 1)商户定义表 CREATE TABLE hope. ...

  10. TEdit的 Clear 和 赋值 ''

    function TControl.GetText: TCaption; var Len: Integer; begin Len := GetTextLen; SetString(Result, PC ...