题意



分析

不难发现把增加人数看成减少人数,上限是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. putty xming gnome-session

    在windows里远程连接linux的最好方法. 比VNC方式好多了 1) xming启动一个窗口 2) putty 设置完X11 forwarding之后,远程登录 3) 在putty 里启动 gn ...

  2. 雷林鹏分享:Ruby 字符串(String)

    Ruby 字符串(String) Ruby 中的 String 对象存储并操作一个或多个字节的任意序列,通常表示那些代表人类语言的字符. 最简单的字符串是括在单引号(单引号字符)内.在引号标记内的文本 ...

  3. Andorid 之日历控件,可左右滑动,包含公历,农历,节假日等

    公司项目需要日历这个功能,经过查阅资料写了个demo,包含公历,农历,节假日等,还可左右滑动. 效果图: 代码: public class MainActivity extends AppCompat ...

  4. 『Networkx』常用方法

    这是一个用于分析'图'结构的包,由于我只是用到了浅显的可视化功能,所以这个介绍会对其使用浅尝辄止. 解决matplotlib中文字体缺失问题, from pylab import mpl mpl.rc ...

  5. kubectl管理多个k8s集群

    #把每个k8s集群的json配置文件放到/root/.kube/目录下,改为不同名字,通过--kubeconfig实现不同集群操作 kubectl --kubeconfig=/root/.kube/m ...

  6. 安装torch-opencv

    安装torch-opencv torch torch-opencv opencv-3.1.0 opencv-contrib 想在torch中使用光流法,于是就希望能够调用opencv中的光流代码,而t ...

  7. 4. Median of Two Sorted Arrays *HARD* -- 查找两个排序数组的中位数(寻找两个排序数组中第k大的数)

    There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...

  8. HeaderExchangeClient

    HeaderExchangeClient 注释是DefaultMessageClient,类中定义了心跳定时器HeaderExchangeChannel 发送请求HeaderExchangeHandl ...

  9. 从输入URL到页面加载发生了什么

    大体过程 浏览器的地址栏输入URL并按下回车 浏览器检查当前URL是否存在缓存,并比较缓存是否过期 DNS解析URL对应的IP 根据IP建立TCP连接(三次握手) HTTP发起请求 服务器处理请求,浏 ...

  10. kill word out 1

    1● de 使~~ 成为 :离开 ,去掉,向下,变慢   2● dif 不,分开 ,否定,离开     3● deci 十分之一   4● deca 向下,离开   5● deca 十   6● di ...