Description
有一个沙漏由两个上下相通玻璃球$A$和$B$构成,这两个玻璃球都含有一定量的沙子,我们暂且假定$A,B$中位于上方的玻璃球的为$U$,下方的玻璃球为$L$,则除非$U$中没有沙子,否则每秒钟都会有$1$克沙子从$U$掉入$L$。

在第$0$个时刻,$A$中有$a$克沙子,$B$中有$X-a$克沙子(总共有$X$克沙子),且$U$为$A$,$L$为$B$(即$A$上$B$下)。

在$r_1,r_2,...,r_K$这些时刻,我们将倒转整个沙漏,使得原来的$U$变成$L$,原来的$L$变成$U$。对于翻转操作,$t$时刻是指从第$0$个时刻起经过$t$秒后的时刻,我们可以将翻转沙漏的操作看做瞬间完成的。

现在有Q次询问,每一次询问会给定一对非负整数$(t_i,a_i)$,求$a=a_i$的第$t_i$时刻,$A$中所含沙子的克数。

Input
第一行一个正整数$X$

第二行一个正整数$K$

第三行$K$个整数,表示$r_1,r_2,...,r_K$

接下来一行一个正整数$Q$

接下来$Q$行,每行两个非负整数,分别表示每次次询问的$(t_i,a_i)$

Output
一共$Q$行

对于每次询问,输出一行一个非负整数表示答案。

数据范围

$1\leq X \leq 10^9$

$1\leq K \leq 10^5$

$1\leq r_1<r_2<...<r_K \leq 10^9$

$1\leq Q \leq 10^5$

$0\leq t_1 < t_2 <...<t_Q\ leq 10^9$

$0\leq a_i \leq X$

题解

不难发现,反转的本质不过是从$A$向$B$流动还是从$B$向$A$流动。

进一步把问题简化,每次$A$中$+1$还是$A$中$-1$,难点在于当数量达到边界时会停止。

再换一个角度考虑,有个数组$a[ \space ]$,每次将它每个数都$+1$或$-1$,到$0$就不减,到$X$时不加,那么考虑从小到大排序,于是它就很显然满足一个性质:

·在任意时刻,所有曾经被下界$0$卡住的$a$一定是个前缀

·在任意时刻,所有曾经被上界$X$卡住(过)的$a$一定是个后缀

于是在任意时刻,这个数组$a$是一个三段的函数。

我在模拟赛上懒得思考了,于是就写了个线段树糊弄过去了。

维护区间最左边(最小)值和最右边(最大)值,分为这三种情况处理,

由于一定是恰好由这三段组成的,所以复杂度大概是$O(n\space 3log(n))$。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define mid (l+r>>1)
#define M 200020
using namespace std;
int read(){
int nm=0,fh=1;char cw=getchar();
for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
return nm*fh;
}
int num[M],p[M<<2][2],tg[M<<2],mk[M<<2];
int n,m,X,R[M],PS[M],tk[M],G[M],tim[M];
bool cmpnum(int i,int j){return G[i]<G[j];}
inline void pushdown(int x){
if(mk[x]>-1){
mk[x<<1]=mk[x<<1|1]=mk[x],tg[x<<1]=tg[x<<1|1]=0;
p[x<<1][0]=p[x<<1|1][0]=mk[x];
p[x<<1][1]=p[x<<1|1][1]=mk[x];
}
if(tg[x]){
tg[x<<1]+=tg[x],tg[x<<1|1]+=tg[x];
p[x<<1][0]+=tg[x],p[x<<1|1][0]+=tg[x];
p[x<<1][1]+=tg[x],p[x<<1|1][1]+=tg[x];
}
mk[x]=-1,tg[x]=0;
}
inline void pushup(int x){p[x][0]=p[x<<1][0],p[x][1]=p[x<<1|1][1];}
void build(int x,int l,int r){
tg[x]=0,mk[x]=-1;
if(l==r){p[x][0]=p[x][1]=num[l];return;}
build(x<<1,l,mid),build(x<<1|1,mid+1,r);
pushup(x);
}
int getnum(int x,int l,int r,int pos){
if(l==r) return p[x][0];
int NUM; pushdown(x);
if(pos<=mid) NUM=getnum(x<<1,l,mid,pos);
else NUM=getnum(x<<1|1,mid+1,r,pos);
pushup(x); return NUM;
}
void add(int x,int l,int r,int dt){
if(p[x][0]+dt>=X) p[x][0]=p[x][1]=mk[x]=X,tg[x]=0;
else if(p[x][1]+dt<=0) p[x][0]=p[x][1]=mk[x]=0,tg[x]=0;
else if(0<=p[x][0]+dt&&p[x][1]+dt<=X){p[x][0]+=dt,p[x][1]+=dt,tg[x]+=dt;}
else pushdown(x),add(x<<1,l,mid,dt),add(x<<1|1,mid+1,r,dt),pushup(x);
}
int main(){
X=read(),m=read();
for(int i=1;i<=m;i++) R[i]=read();
n=read();
for(int i=1;i<=n;i++) tim[i]=read(),G[i]=read(),PS[i]=i;
sort(PS+1,PS+n+1,cmpnum),R[++m]=tim[n]+1;
for(int i=1;i<=n;i++) num[i]=G[PS[i]],tk[PS[i]]=i;
build(1,1,n);
for(int i=1,kd=-1,now=0;i<=m;i++,kd=-kd){
while(now<n&&tim[now+1]<=R[i]){
now++; int x=getnum(1,1,n,tk[now]);
x+=kd*(tim[now]-R[i-1]),printf("%d\n",max(min(x,X),0));
}
add(1,1,n,(R[i]-R[i-1])*kd);
}
return 0;
}

Arc082_F Sandglass的更多相关文章

  1. Sandglass

    题目描述 We have a sandglass consisting of two bulbs, bulb A and bulb B. These bulbs contain some amount ...

  2. 【AtCoder】ARC082 F - Sandglass

    [链接]F - Sandglass [题意]给定沙漏A和B,分别装着a和X-a的沙子,开始时A在上B在下,每秒漏1,漏完不再漏.给定n,有n个时刻ai沙漏倒转.给定m个询问,每次询问给定初值a和时刻t ...

  3. 2017国家集训队作业[arc082d]Sandglass

    2017国家集训队作业[arc082d]Sandglass 题意: ​ 有一个沙漏,初始时\(A\)瓶在上方,两个瓶子的最大容量都为\(X\)克,沙子流动的速度为\(1g\)每单位时间.给出\(K\) ...

  4. 【ARC082D】Sandglass

    Description ​ 题目链接 Description ​ 好题.题意是维护一个初始值,交替加减一段时间,有上界\(m\)和下界0(不能超过这两条界限),问对于某一种初始值,在某一个时刻时该值为 ...

  5. [arc082F]Sandglass

    Description 传送门 Solution 这题是真的666啊... 以下是本题最关键最关键的结论:如果ai<=aj,则在某个时间t,前者的A中沙子克数(记为t(ai))一定大于等于t(a ...

  6. [arc082f]Sandglass 递推

    Description 有一个沙漏由两个上下相通玻璃球A和B构成,这两个玻璃球都含有一定量的沙子,我们暂且假定AB中位于上方的玻璃球的为U,下方的玻璃球为L,则除非U中没有沙子,否则每秒钟都会有1克沙 ...

  7. 【推导】【模拟】AtCoder Regular Contest 082 F - Sandglass

    题意:有个沙漏,一开始bulb A在上,bulb B在下,A内有a数量的沙子,每一秒会向下掉落1.然后在K个时间点ri,会将沙漏倒置.然后又有m个询问,每次给a一个赋值ai,然后询问你在ti时刻,bu ...

  8. [ARC082F] Sandglass(线段树)

    Description 有一个沙漏由两个上下相通玻璃球 \(A\) 和 \(B\) 构成,这两个玻璃球都含有一定量的沙子,我们暂且假定 \(AB\) 中位于上方的玻璃球的为 \(U\),下方的玻璃球为 ...

  9. 【AtCoder Regular Contest 082 F】Sandglass

    [链接]点击打开链接 [题意] 你有一个沙漏. 沙漏里面总共有X单位的沙子. 沙漏分A,B上下两个部分. 沙漏从上半部分漏沙子到下半部分. 每个时间单位漏1单位的沙子. 一开始A部分在上面.然后在r1 ...

随机推荐

  1. Linux进程间通信(四) - 共享内存

    共享内存的优势 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝.对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只 ...

  2. Android JNI开发之NDK环境搭建

    参考:http://www.cnblogs.com/yejiurui/p/3476565.html 谷歌改良了ndk的开发流程,对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本, ...

  3. RecyclerView的使用(3)之加入Header和Footer

    原创文章.转载请注明 http://blog.csdn.net/leejizhou/article/details/50742544 李济洲的博客 RecyclerView尽管作为ListView的替 ...

  4. x^a=b(mod c)求解x在[0,c-1]上解的个数模板+原根求法

    /************************************* 求解x^a=b(mod c) x在[0,c-1]上解的个数模板 输入:1e9>=a,b>=1,1e9>= ...

  5. 【BZOJ3747】[POI2015]Kinoman 线段树

    [BZOJ3747][POI2015]Kinoman Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第 ...

  6. 【BZOJ2724】[Violet 6]蒲公英 分块+二分

    [BZOJ2724][Violet 6]蒲公英 Description Input 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n ...

  7. EasyDarwin开源流媒体服务器Golang版本:服务端录像功能发布

    EasyDarwin开源流媒体服务器(www.easydarwin.org)现在使用Go版本实现了.最新的代码提交,已经支持了推流(或者拉流)的同时进行本地存储. 本地存储的原理,是在推流的同时启动f ...

  8. iptables的用例

    iptables书写思路顺序 1.协议 icmp 2.哪个功能和目标:过滤,拒绝 3.数据包流向:外到内 4.哪个链适合:越早越好,INPUT 5.源地址和目标地址 练习1.禁止某些主机或网络访问本机 ...

  9. Effective Java 读书笔记(一):使用静态工厂方法代替构造器

    这是Effective Java第2章提出的第一条建议: 考虑用静态工厂方法代替构造器 此处的静态工厂方法并不是设计模式,主要指static修饰的静态方法,关于static的说明可以参考之前的博文&l ...

  10. lua解析json

    自己写的lua解析json,带容错,如果要是用于格式检查,得修改下.很简单直接贴代码 --------------------------------------------------json解析- ...