# [Ahoi2014]奇怪的计算器 解题报告

562人阅读 评论(0)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;
#include<cstdlib>
#include<algorithm>
const int N=1e5+5,Q=1e5+5;
typedef long long LL;
int L,R;

char * cp=(char *)malloc(3000000);
void in(int &x){
while(*cp<'0'||*cp>'9')++cp;
for(x=0;*cp>='0'&&*cp<='9';)x=x*10+(*cp++^'0');
}
void in(char &c){
while(*cp!='+'&&*cp!='-'&&*cp!='*'&&*cp!='@')++cp;
c=*cp++;
}
char * os=(char *)malloc(2000000),*op=os;
void out(int x){
if(x){
out(x/10);
*op++='0'+x%10;
}
}

struct OS{
char opt;
int a;
}order[N];

struct QS{
int x;
int i;
bool operator < (const QS & o)const{
return x<o.x;
}
}a[Q];
int ans[Q];

struct SS{
int k,b0,b1;
int l,r;
}segt[Q<<2];
#define lson node<<1,l,l+r>>1
#define rson node<<1|1,(l+r>>1)+1,r
void out(int node,int l,int r){
printf("%d[%d,%d]={k=%d,b0=%d,b1=%d,l=%d,r=%d}\n",node,l,r,segt[node].k,segt[node].b0,segt[node].b1,segt[node].l,segt[node].r);
}
void paint(int node,int l,int r,int k,int b0,int b1){
//printf("paint(%d,%d,%d,%I64d,%I64d,%I64d)\n",node,l,r,k,b0,b1);
segt[node]=(SS){segt[node].k*k,segt[node].b0*k+b0,segt[node].b1*k+b1,segt[node].l*k+b0*a[l].x+b1,segt[node].r*k+b0*a[r].x+b1};
}
void pushdown(int node,int l,int r){
if(segt[node].k!=1||segt[node].b0||segt[node].b1){
paint(lson,segt[node].k,segt[node].b0,segt[node].b1),paint(rson,segt[node].k,segt[node].b0,segt[node].b1);
segt[node].k=1,segt[node].b0=segt[node].b1=0;
}
}
void pushup(int node){
segt[node].l=segt[node<<1].l;
segt[node].r=segt[node<<1|1].r;
//printf("%d:%I64d,%I64d\n",node,segt[node<<1].l,segt[node<<1|1].r);
}
int cal(int data,int x,int k,int b0,int b1){
return min((LL)k*data+(LL)b0*x+b1,R+1LL);
}
void build(int node,int l,int r){
segt[node].k=1,segt[node].b0=segt[node].b1=0;
if(l==r)segt[node].l=segt[node].r=a[l].x;
else{
build(lson),build(rson);
pushup(node);
}
}
void rquery(int node,int l,int r,int k,int b0,int b1){
//printf("rquery(%d,[%d,%d],%d,%d,%d)\n",node,l,r,k,b0,b1);
//printf("cal(%d)=%d\n",l,cal(segt[node].l,a[l].x,k,b0,b1));
if(cal(segt[node].r,a[r].x,k,b0,b1)<=R)paint(node,l,r,k,b0,b1);
else
if(cal(segt[node].l,a[l].x,k,b0,b1)>R)paint(node,l,r,0,0,R);
else{
pushdown(node,l,r);
if(cal(segt[node<<1].r,a[l+r>>1].x,k,b0,b1)>R){
paint(rson,0,0,R);
rquery(lson,k,b0,b1);
}
else{
paint(lson,k,b0,b1);
rquery(rson,k,b0,b1);
}
pushup(node);
}
//out(node,l,r);
}
void lquery(int node,int l,int r,int k,int b0,int b1){
if(cal(segt[node].l,a[l].x,k,b0,b1)>=L)paint(node,l,r,k,b0,b1);
else
if(cal(segt[node].r,a[r].x,k,b0,b1)<L)paint(node,l,r,0,0,L);
else{
pushdown(node,l,r);
if(cal(segt[node<<1|1].l,a[(l+r>>1)+1].x,k,b0,b1)<L){
paint(lson,0,0,L);
lquery(rson,k,b0,b1);
}
else{
paint(rson,k,b0,b1);
lquery(lson,k,b0,b1);
}
pushup(node);
}
//out(node,l,r);
}
void query(int node,int l,int r){
if(l==r)ans[a[l].i]=segt[node].l;
else{
pushdown(node,l,r);
query(lson),query(rson);
}
}
int main(){
freopen("calc8.in","r",stdin);
freopen("bzoj_3878.out","w",stdout);
int n;
in(n),in(L),in(R);
for(int i=1;i<=n;++i)in(order[i].opt),in(order[i].a);
int q;
in(q);
for(int i=1;i<=q;++i){
in(a[i].x);
a[i].i=i;
}
sort(a+1,a+q+1);
build(1,1,q);
for(int i=1;i<=n;++i)
switch(order[i].opt){
case '+':
rquery(1,1,q,1,0,order[i].a);
break;
case '-':
lquery(1,1,q,1,0,-order[i].a);
break;
case '*':
rquery(1,1,q,order[i].a,0,0);
break;
case '@':
rquery(1,1,q,1,order[i].a,0);
break;
}
query(1,1,q);
for(int i=1;i<=q;++i){
if(ans[i])out(ans[i]);
else *op++='0';
*op++='\n';
}
fwrite(os,1,op-os,stdout);
}

①一定要算好量的范围！！
②对于中间量可能很大，结果量很小的情况，我们可以在模意义下去运算它。——参考O(1)$O(1)$快速乘的思想。

0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：166069次
• 积分：3545
• 等级：
• 排名：第10764名
• 原创：187篇
• 转载：1篇
• 译文：0篇
• 评论：25条
评论排行
最新评论