BZOJ 3878 【AHOI2014】 奇怪的计算器
题目链接:奇怪的计算器
如果没有溢出的话,所有的标记都可以在线段树上直接维护,所以一棵线段树就解决问题了。
现在有了溢出,怎么办呢?
发现就算溢出了,各个元素的相对大小关系也是不变的。所以,如果一开始就把元素排好序,溢出的数一定是两段区间。在线段树上把这两段区间找出来,区间赋值就好了。当然也需要多记录区间\(\max\)和区间\(\min\)。
PS:注意各个标记的先后关系
下面贴代码(代码较丑):
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 100010
#define MAXN maxn<<2 using namespace std;
typedef long long llg; struct data{
int x,b;
bool operator < (const data &h)const{return x<h.x;}
}b[maxn],s[maxn];
int n,m,ZL,ZR,a[maxn],ans[maxn];
llg maxv[MAXN],minv[MAXN],che[MAXN];
llg add1[MAXN],add2[MAXN],set[MAXN]; int getint(){
int w=0;bool q=0;
char c=getchar();
while((c>'9'||c<'0')&&c!='-') c=getchar();
if(c=='-') c=getchar(),q=1;
while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar();
return q?-w:w;
} void gch(int u,int x){minv[u]*=x,maxv[u]*=x,che[u]*=x;}
void ga1(int u,int x){minv[u]+=x,maxv[u]+=x,add1[u]+=x;}
void gset(int u,int x){
set[u]=maxv[u]=minv[u]=x;
add1[u]=add2[u]=0; che[u]=1;
} void pushdown(int u,int l,int r){
int lc=u<<1,lv=u<<1|1,mid=(l+r)>>1;
if(set[u]) gset(lc,set[u]),gset(lv,set[u]);
if(che[u]>1) gch(lc,che[u]),gch(lv,che[u]);
if(add1[u]) ga1(lc,add1[u]),ga1(lv,add1[u]);
if(add2[u]){
minv[lc]+=add2[u]*a[l]; maxv[lc]+=add2[u]*a[mid];
minv[lv]+=add2[u]*a[mid+1],maxv[lv]+=add2[u]*a[r];
add2[lc]+=add2[u],add2[lv]+=add2[u];
}
set[u]=add1[u]=add2[u]=0; che[u]=1;
} void update(int u){minv[u]=minv[u<<1],maxv[u]=maxv[u<<1|1];}
void build(int u,int l,int r){
int lc=u<<1,lv=u<<1|1,mid=(l+r)>>1; che[u]=1;
if(l==r){maxv[u]=minv[u]=a[l];return;}
build(lc,l,mid),build(lv,mid+1,r);
update(u);
} void queryl(){
if(maxv[1]<=ZL){gset(1,ZL);return;}
int u=1,l=1,r=m,mid;
while(l!=r){
pushdown(u,l,r);
mid=(l+r)>>1; u<<=1;
if(maxv[u]>=ZL) r=mid;
else gset(u,ZL),l=mid+1,u^=1;
}
while(u>1) u>>=1,update(u);
} void queryr(){
if(minv[1]>=ZR){gset(1,ZR);return;}
int u=1,l=1,r=m,mid;
while(l!=r){
pushdown(u,l,r);
mid=(l+r)>>1; u<<=1; u|=1;
if(minv[u]<=ZR) l=mid+1;
else gset(u,ZR),r=mid,u^=1;
}
while(u>1) u>>=1,update(u);
} void dfs(int u,int l,int r){
int lc=u<<1,lv=u<<1|1,mid=(l+r)>>1;
if(l==r) ans[s[l].b]=maxv[u];
else{
pushdown(u,l,r);
dfs(lc,l,mid),dfs(lv,mid+1,r);
}
} int main(){
File("a");
n=getint(),ZL=getint(),ZR=getint();
for(int i=1;i<=n;i++){
char c=getchar();
while(c!='+' && c!='-' && c!='*' && c!='@') c=getchar();
b[i].x=getint();
if(c=='+') b[i].b=1; if(c=='-') b[i].b=2;
if(c=='*') b[i].b=3; if(c=='@') b[i].b=4;
}
m=getint();
for(int i=1;i<=m;i++) s[i].x=getint(),s[i].b=i;
sort(s+1,s+m+1);
for(int i=1;i<=m;i++) a[i]=s[i].x;
build(1,1,m);
dfs(1,1,m);
for(int i=1,x,tp;i<=n;i++){
tp=b[i].b,x=b[i].x;
if(tp==1) ga1(1,x); if(tp==2) ga1(1,-x); if(tp==3) gch(1,x);
if(tp==4) add2[1]+=x,minv[1]+=1ll*a[1]*x,maxv[1]+=1ll*a[m]*x;
queryl(); queryr();
//dfs(1,1,m);
}
dfs(1,1,m);
for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
return 0;
}
BZOJ 3878 【AHOI2014】 奇怪的计算器的更多相关文章
- BZOJ 3878: [Ahoi2014]奇怪的计算器
BZOJ 3878: [Ahoi2014]奇怪的计算器 标签(空格分隔): OI-BZOJ OI-线段树 Time Limit: 10 Sec Memory Limit: 256 MB Descrip ...
- AHOI2014 奇怪的计算器 和 HDU5306 Gorgeous Sequence
线段树秀操作题. 奇怪的计算器 有 N 个数,一共会对这 N 个数执行 M 个指令(对没个数执行的指令都一样),每一条指令可以是以下四种指令之一:(这里 a 表示一个正整数) 加上 a 减去 a 乘以 ...
- BZOJ3878: [Ahoi2014&Jsoi2014]奇怪的计算器
BZOJ3878: [Ahoi2014&Jsoi2014]奇怪的计算器 Description [故事背景] JYY有个奇怪的计算器,有一天这个计算器坏了,JYY希望你能帮助他写 一个程序来模 ...
- 「AHOI2014/JSOI2014」奇怪的计算器
「AHOI2014/JSOI2014」奇怪的计算器 传送门 我拿到这题首先是懵b的,因为感觉没有任何性质... 后来经过同机房dalao的指导发现可以把所有的 \(X\) 放到一起排序,然后我们可以发 ...
- BZOJ 3873: [Ahoi2014]拼图
BZOJ 3873: [Ahoi2014]拼图 标签(空格分隔): OI-BZOJ OI-DP Time Limit: 10 Sec Memory Limit: 256 MB Description ...
- BZOJ 3878 [AHOI&JSOI2014]奇怪的计算器 (线段树)
题面:BZOJ传送门 洛谷传送门 线段树好题 题目保证$a$一定是正整数,容易发现计算结果是单调的 我们把询问离线,并按照从小到大排序 某次操作可能导致某些位置达到边界$L/R$ 根据单调性的结论 这 ...
- 2018.07.25 bzoj3878: [Ahoi2014&Jsoi2014]奇怪的计算器(线段树)
传送门 线段树综合. 让我想起一道叫做siano" role="presentation" style="position: relative;"&g ...
- AHOI2014/JSOI2014 奇怪的计算器
题目描述 题解: 考虑到经过一系列变化后小数不可能比大数大,我们可以用线段树维护区间修改. 重点是,每个节点都可以通过$a[i]=a[i]*t1+a0[i]*t2+t3$这个函数来表示,我们就可以把三 ...
- BZOJ 2756: [SCOI2012]奇怪的游戏 [最大流 二分]
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 3352 Solved: 919[Submit][Stat ...
随机推荐
- Python+OpenCV图像处理(二)——打印图片属性、设置图片存储路径、电脑摄像头的调取和显示
一. 打印图片属性.设置图片存储路径 代码如下: #打印图片的属性.保存图片位置 import cv2 as cv import numpy as np #numpy是一个开源的Python科学计算库 ...
- jboss 报错处理及端口修改
执行文件 ./shutdown.sh -S 后 重启jboss 执行 ./run.sh -Djboss.bind.address=192.168.132.129 & 如果一台机器安装多个jbo ...
- javaweb笔记09—(session会话及验证码问题)
第一部分+++++++++++1.session会话 定义:session会话——对某个web应用程序的一次整体访问的过程. 由来:无连接的http协议是无状态的,不能保存每个客户端私有信息 a用户和 ...
- MyEclipse项目的jquery.js发生[Multiple markers at this line - Missing semicolon]的解决方案
问题描述: 导入jquery库后,发现提示错误信息:Multiple markers at this line - Missing semicolon,如下截图所示: 解决方案: 选中该jquery. ...
- Python基本数据类型——字典
字典 dict 字典是Python的另一种有序的可变数据结构,且可存储任意类型对象. 字典是一种键值对的数据容器,每个键值(key:value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典 ...
- Python3 join函数和os.path.join用法
Python3 join函数和os.path.join用法 os.path.join()连接两个文件名地址的时候,就比os.path.join("D:\","test. ...
- 【题解】Luogu P1503 鬼子进村
平衡树好题 原题传送门 这道题要用Splay,我博客里有对Splay的详细介绍 这道题思维有点难,要把被摧毁的节点插入平衡树,而不是把没有摧毁的节点插入 先把0和n+1插入平衡树,作为边界 操作1:摧 ...
- Python学习基础(三)——装饰器,列表生成器,斐波那契数列
装饰器——闭包 # 装饰器 闭包 ''' 如果一个内部函数对外部(非全局)的变量进行了引用,那么内部函数被认为是闭包 闭包 = 函数块 + 定义时的函数环境 ''' def f(): x = 100 ...
- [c/c++] programming之路(7)、数据类型转换、偷钱小程序、进制转换
一.数据类型转换 #include<stdio.h> //某些场合,必须进行数据类型转换,以匹配调用 void main0(){ printf();//printf不管你是什么类型,解析失 ...
- Codeforces 37D Lesson Timetable - 组合数学 - 动态规划
题目传送门 神奇的门I 神奇的门II 题目大意 有$n$组学生要上课2次课,有$m$个教室,编号为$1$到$m$.要确定有多少种不同的安排上课的教室的方案(每组学生都是本质不同的),使得它们满足: 每 ...