zjoi[ZJOI2018]胖
题解:
因为n,m很大
所以复杂度应该是和m相关的
考虑到每个点的影响区间是连续的
就很简单了
区间查询最小值线段树维护(st表也可以)
然后注意一下不要重复算一个就可以了
max函数用template<class T> 不能与原来min重名
代码:
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define IL inline
#define rint register int
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
const int N=3e5;
const ll INF=1e18;
const int N2=1e7;
ll dis[N],sum1[N],sum2[N];
int n,m,cnt;
struct re{
int a;
ll b;
};
vector<int> ve;
ll data1[N2],data2[N2];
int ls[N2],rs[N2];
char ss[<<],*A=ss,*B=ss;
IL char gc()
{
return (A==B&&(B=(A=ss)+fread(ss,,<<,stdin),A==B)?EOF:*A++);
}
template<class T>void read(T &x)
{
rint f=,c; while (c=gc(),c<||c>) if (c=='-') f=-; x=c^;
while (c=gc(),<c&&c<) x=(x<<)+(x<<)+(c^); x*=f;
}
char sr[<<],z[]; int C=-,Z;
template <class T> void wer(T x)
{
if (x<) sr[++C]='-',x=-x;
while (z[++Z]=x%+,x/=);
while (sr[++C]=z[Z],--Z); sr[++C]='\n';
}
template<class T> T MAX(T x,T y)
{
if (x>y) return(x); else return(y);
}
template<class T> T MIN(T x,T y)
{
if (x<y) return(x); else return(y);
}
IL void swap(int &x,int &y)
{
int tmp=x; x=y; y=tmp;
}
void clear()
{
cnt=;
for (int i=;i<ve.size();i++)
{
int x=ve[i];
data1[x]=INF; data2[x]=INF; ls[x]=; rs[x]=;
}
ve.clear();
}
void updata(int x)
{
data1[x]=MIN(data1[ls[x]],data1[rs[x]]);
data2[x]=MIN(data2[ls[x]],data2[rs[x]]);
}
void change(int &x,int h,int t,int pos,ll k)
{
if (!x) x=++cnt;
ve.push_back(x);
if (h==t)
{
data1[x]=MIN(data1[x],sum1[pos-]+k);
data2[x]=MIN(data2[x],sum2[pos]+k);
return;
}
int mid=(h+t)/;
if (pos<=mid) change(ls[x],h,mid,pos,k);
else change(rs[x],mid+,t,pos,k);
updata(x);
}
ll query1(int x,int h,int t,int h1,int t1)
{
if (!x) return(INF);
if (h1<=h&&t<=t1) return(data1[x]);
ll ans=INF;
int mid=(h+t)/;
if (h1<=mid) ans=query1(ls[x],h,mid,h1,t1);
if (mid<t1) ans=MIN(ans,query1(rs[x],mid+,t,h1,t1));
return(ans);
}
ll query2(int x,int h,int t,int h1,int t1)
{
if (!x) return(INF);
if (h1<=h&&t<=t1) return(data2[x]);
ll ans=INF;
int mid=(h+t)/;
if (h1<=mid) ans=query2(ls[x],h,mid,h1,t1);
if (mid<t1) ans=MIN(ans,query2(rs[x],mid+,t,h1,t1));
return(ans);
}
IL ll check1(int h,int t,int x)
{
h=MAX(h,); t=MIN(t,n);
return(query2(,,n,h,t)-sum2[x]);
}
IL ll check2(int h,int t,int x)
{
h=MAX(h,); t=MIN(t,n);
return(query1(,,n,h,t)-sum1[x-]);
}
int main()
{
read(n); read(m);
rep(i,,n-) read(dis[i]);
rep(i,,n-) sum1[i]=dis[i],sum1[i]+=sum1[i-];
dep(i,n-,) sum2[i]=dis[i],sum2[i]+=sum2[i+];
rep(i,,N2-) data1[i]=INF,data2[i]=INF;
rep(i,,m)
{
int x,y;
ll ans=,z;
read(x);
vector<re> ve1;
ve1.push_back((re){,});
clear();
int root=;
rep(j,,x)
{
read(y); read(z);
change(root,,n,y,z);
ve1.push_back((re){y,z});
}
rep(j,,x)
{
int y=ve1[j].a;
ll z=ve1[j].b;
int h=y,t=n;
while (h<t)
{
int mid=(h+t+)/;
ll jl=sum1[mid-]-sum1[y-]+z;
if (MIN(check1(y+,mid,mid),check2(mid,*mid-y-,mid))>jl&&
check2(*mid-y,*mid-y,mid)>=jl) h=mid;
else t=mid-;
}
ans+=t-y;
h=,t=y;
while (h<t)
{
int mid=(h+t)/;
ll jl=sum1[y-]-sum1[mid-]+z;
if (MIN(check2(mid,y-,mid),check1(*mid-y+,mid,mid))>jl&&
check1(*mid-y,*mid-y,mid)>jl) t=mid;
else h=mid+;
}
ans+=y-h+;
}
wer(ans);
}
fwrite(sr,,C+,stdout);
return ;
}
zjoi[ZJOI2018]胖的更多相关文章
- 【BZOJ5308】[ZJOI2018]胖(模拟,ST表,二分)
[BZOJ5308][ZJOI2018]胖(模拟,ST表,二分) 题面 BZOJ 洛谷 题解 首先发现每条\(0\)出发的边都一定会更新到底下的一段区间的点. 考虑存在一条\(0\rightarrow ...
- 5308: [Zjoi2018]胖
5308: [Zjoi2018]胖 链接 分析: 题目转化为一个点可以更新多少个点,一个点可以更新的点一定是一个区间,考虑二分左右端点确定这个区间. 设当前点是x,向右二分一个点y,如果x可以更新到y ...
- P4501 [ZJOI2018]胖
题目 P4501 [ZJOI2018]胖 官方口中的送分题 做法 我们通过手玩(脑补),\(a_i\)所作的贡献(能更新的点)为:在\(a_i\)更新\(\forall x\)更新前前没有其他点能把\ ...
- [ZJOI2018]胖
嘟嘟嘟 都说这题是送分题,但我怎么就不觉得的呢. 看来我还是太弱了啊-- 大体思路就是对于每一个设计方案,答案就是每一个关键点能更新的点的数量之和. 关键在于怎么求一个关键点能更新那些点. 首先这些点 ...
- ZJOI2018 胖 二分 ST表
原文链接https://www.cnblogs.com/zhouzhendong/p/ZJOI2018Day2T2.html 题目传送门 - BZOJ5308 题目传送门 - LOJ2529 题目传送 ...
- 2019.03.04 bzoj5308: [Zjoi2018]胖(二分答案+st表)
传送门 想题5分钟调题两小时系列 其实还是我tcl 读完题之后自然会知道一个关键点能够更新的点是一段连续的区间,于是我们对于每个点能到的左右区间二分答案,用ststst表维护一下查询即可. 代码: # ...
- BZOJ5308 ZJOI2018胖
贝尔福特曼(?)的方式相当于每次将所有与源点直接相连的点的影响区域向两边各扩展一格.显然每个点在过程中最多更新其他点一次且这些点构成一段连续区间.这个东西二分st表查一下就可以了.注意某一轮中两点都更 ...
- 洛谷P4501/loj#2529 [ZJOI2018]胖(ST表+二分)
题面 传送门(loj) 传送门(洛谷) 题解 我们对于每一个与宫殿相连的点,分别计算它会作为多少个点的最短路的起点 若该点为\(u\),对于某个点\(p\)来说,如果\(d=|p-u|\),且在\([ ...
- bzoj 5308: [Zjoi2018]胖
Description Cedyks是九条可怜的好朋友(可能这场比赛公开以后就不是了),也是这题的主人公. Cedyks是一个富有的男孩子.他住在著名的ThePLace(宫殿)中. Cedyks是一个 ...
随机推荐
- python用WMI模块获取系统命名空间
可以和winmgmts的查询页面对应 from win32com.client import GetObject import pywintypes result=[] def enum_namesp ...
- 链接器link.exe 编译器cl.exe 资源编译器rc.exe
原文地址:https://blog.csdn.net/biggbang/article/details/24433065 1.cl.exe文件是Visual C\C++的编译器,它将程序源代码文件编译 ...
- <图文教程>VMware 14上Ubuntu 16.04 desktop版的安装
VMware14安装Ubuntu16.04教程 久闻Linux(这单词念做 林尼克斯??)大名,闲来无事就试着给自己笔记本装一个玩玩,从朋友口中得知可以在Vmware上装虚拟机,就自己试着尝试一下,顺 ...
- Apache服务器和tomcat服务器有什么区别(转)
Apache与Tomcat都是Apache开源组织开发的用于处理HTTP服务的项目,两者都是免费的,都可以做为独立的Web服务器运行.Apache是Web服务器而Tomcat是Java应用服务器. A ...
- 行为驱动:BDD框架之Cucumber初探
1.cucumber cucumber早在ruby环境下应用广泛,作为BDD框架的先驱,cucumber后来被移植到了多平台,简单来说cucumber是一个测试框架,就像是juint或是rspec一样 ...
- [Linux]流媒体服务器概述
二.何为流媒体与流式传输? 2.1 流媒体 「流媒体」是指采用「流式传输」的方式在Internet播放的媒体格式,流媒体最大的特点就是「边下边播」,常用的流媒体格式有FLV(使用FLASH作为视频播放 ...
- Confluence 6 在你用户宏中使用参数
你可以为你的用户宏指定参数.这样的话,用户可以使用参数来决定 Confluence 页面的显示情况. 如何在 Confluence 页面中使用你的宏参数 当添加一个宏到 Confluence 页面中的 ...
- ionic3 点击input 弹出白色遮罩 遮挡上部内容
在Manifest中的activity里设置android:windowSoftInputMode为adjustPan,默认为adjustResize,当前窗口的内容将自动移动以便当前焦点从不被键盘覆 ...
- linux 使用的部分命令
搜索所有运行着的线程 ps -A | grep apt-get 你会得到类似下面的输出: root ? Ss : : /bin/sh /usr/lib/apt/apt.systemd.daily _a ...
- linux命令中的参数前的一横(-)和两横(--)的区别
在解释这些区别之前我们先了解一下有关linux的背景知识,这个需要大家先认真看完就会对这些区别有更深入的了解,对linux也有更深的了解. 关于System V和BSD风格以及他们与Linux的关系: ...