test20180919 选择客栈
题意


分析
不难发现把增加人数看成减少人数,上限是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 选择客栈的更多相关文章
- NOIP2011选择客栈[递推]
题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均 ...
- 选择客栈noip2011
哈,没想到吧.今天居然有两篇(算什么,厕所读物吗 选择客栈 本题的更优解请跳转zt 这题11年,刚改2day. 对于30% 的数据,有 n ≤100: 对于50% 的数据,有 n ≤1,000: 对于 ...
- 一本通1546【NOIP2011】选择客栈
1546:NOIP2011 选择客栈 时间限制: 1000 ms 内存限制: 524288 KB 题目描述 丽江河边有 n 家很有特色的客栈,客栈按照其位置顺序从 1 到 n 编号. ...
- 洛谷 P1311 选择客栈 解题报告
P1311 选择客栈 题目描述 丽江河边有 \(n\) 家很有特色的客栈,客栈按照其位置顺序从 \(1\) 到 \(n\) 编号.每家客栈都按照某一种色调进行装饰(总共 \(k\) 种,用整数 \(0 ...
- 洛谷P1311 选择客栈
P1311 选择客栈 题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一 ...
- 【11NOIP提高组】选择客栈(信息学奥赛一本通 1546)(洛谷 1311)
题目描述 丽江河边有nn家很有特色的客栈,客栈按照其位置顺序从 11到nn编号.每家客栈都按照某一种色调进行装饰(总共 kk 种,用整数 00 ~k-1k−1 表示),且每家客栈都设有一家咖啡店,每家 ...
- Noip2011 提高组 选择客栈
P1311 选择客栈 直通 思路: ①看题,我们可以发现一个显然的性质,即当最左边的客栈向右移动时,最右边的客栈时单调向右的,并且右端点往右的客栈也符合要求.(因为只要左侧有一个满足的,右边的自然可以 ...
- 【五一qbxt】day7-2 选择客栈
停更20天祭qwq(因为去准备推荐生考试了一直在自习qwq) [noip2011选择客栈] 这道题的前置知识是DP,可以参考=>[五一qbxt]day3 动态规划 鬼知道我写的是什么emm 这道 ...
- luoguP1311 选择客栈 题解(NOIP2011)
P1311 选择客栈 题目 #include<iostream> #include<cstdlib> #include<cstdio> #include<c ...
随机推荐
- 基于netty框架的socket长连接负载均衡解决方案
socket通讯的单机瓶颈 物联网的项目socket使用方式有两种: 短连接的socket请求 维持socket长连接的请求 对于socket短链接来说就好比是http请求,请求服务器,服务器返回数据 ...
- Linux 虚拟内存和物理内存的理解
关于Linux 虚拟内存和物理内存的理解. 首先,让我们看下虚拟内存: 第一层理解 1. 每个进程都有自己独立的4G内存空间,各个进程的内存空间具有类似的结构 2. 一个新进程建立的时候,将会建立起自 ...
- 使用nginx+dnsmasq解决同IP不同端口Session冲突问题
由于一台服务器上需要部署多个项目,而我们的WEB项目因为用到框架都是一样的,导致同时运行,session相互冲突,这个登录后,那个就得重新登录,造成了使用不方便,原因是IP相同认为是同一个域,接收了B ...
- 『OpenCV3』处理视频&摄像头
在opencv中,摄像头和视频文件并没有很大不同,都是一个可以read的数据源,使用cv2.VideoCapture(path).read()可以获取(flag,当前帧),对于每一帧,使用图片处理函数 ...
- python-day20--正则表达式与re模块
1.通过re模块可以做一些关于正则的相关操作 2.正则表达式:做字符串匹配的规则 1)字符组:在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[ ]表示 [0-9][a-f][A-F] ...
- idea中使用gradle
idea中使用gradle gradle下载 gradle下载地址:https://services.gradle.org/distributions/ 这里假设下载的是4.6版本的,如下: 笔者下载 ...
- JavaScript学习总结(十四)——JavaScript编写类的扩展方法
在JavaScript中可以使用类的prototype属性来扩展类的属性和方法,在实际开发当中,当JavaScript内置的那些类所提供的动态 ...
- memory prefix un,under,uni out1
1● un 不 非,无 打开 ,解开 ,开出 2● under ʌnd ə 向下,副 的,不足的 3● uni 单一 ,单
- ADO.NET Entity Framework -Code Fisrt 开篇(一)
ADO.NET Entity Framework -Code Fisrt 开篇(一) 2012-12-25 15:13 by 易code, 911 阅读, 0 评论, 收藏, 编辑 ADO.NET E ...
- [Android Studio] Android Studio常用快捷键
[Android Studio] Android Studio常用快捷键 (会持续更新)这边讲的常用快捷键是指做完Keymap到Eclipse后的,不是纯Android Studio的,这边主要讲 ...