Description
【故事背景】
JYY有个奇怪的计算器,有一天这个计算器坏了,JYY希望你能帮助他写
一个程序来模拟这个计算器的运算。
【问题描述】
JYY的计算器可以执行N条预设好的指令。每次JYY向计算器输入一个正
整数X,计算器就会以X作为初始值,接着依次执行预设的N条指令,最后把
最终得出的结果返回给JYY。
每一条指令可以是以下四种指令之一:(这里a表示一个正整数。)
1、+a:表示将当前的结果加上a;
2、-a:表示将当前的结果减去a;
3、*a:表示将当前的结果乘以a;
4、@a:表示将当前的结果加上a*X(X是一开始JYY输入的数)。
计算器用于记录运算结果的变量的存储范围是有限的,所以每次运算结束之
后会有计算结果溢出的问题。
JYY的计算器中,存储每计算结果的变量只能存储L到R之间的正整数,
如果一次指令执行过后,计算结果超过了R,那么计算器就会自动把结果变成R,然后再以R作为当前结果继续进行之后的计算。同理,如果运算结果小于L,计算器也会把结果变成L,再接着计算。
比如,假设计算器可以存储1到6之间的值,如果当前的计算结果是2,那
么在执行+5操作之后,存储结果的变量中的值将会是6。虽然2+5的实际结
果是7,但是由于7超过了存储范围的上界,所以结果就被自动更正成了上界的大小,也就是6。
JYY一共想在计算器上输入Q个值,他想知道这Q个值输入计算器之后,
分别会得到什么结果呢?
Input
输入文件的第一行包含三个正整数,N,L和R;
第接下来N行,每行一个指令,每个指令如题述,由一个字符和一个正整
数组成,字符和正整数中间有一个空格隔开;
第N+2行包含一个整数Q,表示JYY希望输入的数的数量;
第接下来Q行每行一个正整数,第k个正整数Xk表示JYY在第k次输入的
整数。
Output
输出Q行每行一个正整数,第k行的整数表示输入Xk后,依次经过N个指
令进行计算所得到的结果。
Sample Input
5 1 6
+ 5
- 3
* 2
- 7
@ 2
3
2
1
5
+ 5
- 3
* 2
- 7
@ 2
3
2
1
5
Sample Output
5
3
6
3
6
HINT
【样例说明】
当JYY输入2时,计算器会进行5次运算,每一次运算之后得到的结果分
别是6(实际计算结果为7但是超过了上界),3,6,1(实际结果为-1但是低于了下界)和5(由于一开始输入的是2,所以这一次计算为1+2×2)。
1<=N,Q<=10^5,1<=L<=Xk<=R<=10^9,1<=a<=10^9
【其实也是JSOI2014 第二轮D2T3】
总觉得现在去省选现场还是做不出这种题目。
第一眼看到JYY和序列操作有关我就猜到是线段树。【题目很明显是数据结构,而这种操作几乎都是线段树】
关键是怎么来维护操作。
可以很明显地发现,所有操作均不改变数的相对大小【若x<y,则操作后x<=y】【现场做题时也就想到这里了】
所以我们可以排序。然后所有数一起操作。
不过这样肯定会超时的。我们又可以发现,所有会超过边界的一定是最左边一段或者最右边一段。
那么我们对于这一段可以直接区间赋值。对于一段内没有任何数超过边界的也可以区间进行操作
那么这个问题就解决了
【结果还是调了好久。代码还写的是最长】
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
struct tree
{
int l,r;
long long x,lx;
long long m,lm;
long long mi,lmi;
long long tag;
long long tag1,tag2,tag3;
}tr[800001];
struct number
{
int x,t;
bool operator <(number y) const
{
return x<y.x;
}
}a[100001];
struct question
{
int p,x;
}ask[100001];
int fx[100001];
int ll,rr;
inline void up(int p)
{
tr[p].m=max(tr[p*2].m,tr[p*2+1].m);
tr[p].lm=max(tr[p*2].lm,tr[p*2+1].lm);
tr[p].mi=min(tr[p*2].mi,tr[p*2+1].mi);
tr[p].lmi=min(tr[p*2].lmi,tr[p*2+1].lmi);
}
inline void down(int p)
{
if(tr[p].tag!=0)
{
tr[p*2].m=tr[p].tag;
tr[p*2+1].m=tr[p].tag;
tr[p*2].mi=tr[p].tag;
tr[p*2+1].mi=tr[p].tag;
tr[p*2].tag2=1;
tr[p*2].tag1=0;
tr[p*2].tag3=0;
tr[p*2+1].tag2=1;
tr[p*2+1].tag1=0;
tr[p*2+1].tag3=0;
tr[p*2].tag=tr[p].tag;
tr[p*2+1].tag=tr[p].tag;
tr[p].tag=0;
}
tr[p*2].m*=tr[p].tag2;
tr[p*2].m+=tr[p].tag1;
tr[p*2].m+=tr[p].tag3*tr[p*2].lm;
tr[p*2+1].m*=tr[p].tag2;
tr[p*2+1].m+=tr[p].tag1;
tr[p*2+1].m+=tr[p].tag3*tr[p*2+1].lm;
tr[p*2].mi*=tr[p].tag2;
tr[p*2].mi+=tr[p].tag1;
tr[p*2].mi+=tr[p].tag3*tr[p*2].lmi;
tr[p*2+1].mi*=tr[p].tag2;
tr[p*2+1].mi+=tr[p].tag1;
tr[p*2+1].mi+=tr[p].tag3*tr[p*2+1].lmi;
tr[p*2].tag2*=tr[p].tag2;
tr[p*2].tag1=tr[p*2].tag1*tr[p].tag2+tr[p].tag1;
tr[p*2].tag3=tr[p*2].tag3*tr[p].tag2+tr[p].tag3;
tr[p*2+1].tag2*=tr[p].tag2;
tr[p*2+1].tag1=tr[p*2+1].tag1*tr[p].tag2+tr[p].tag1;
tr[p*2+1].tag3=tr[p*2+1].tag3*tr[p].tag2+tr[p].tag3;
tr[p].tag2=1;
tr[p].tag1=0;
tr[p].tag3=0;
}
inline void build(int p,int l,int r)
{
tr[p].l=l;
tr[p].r=r;
if(l!=r)
{
int mid=(l+r)/2;
if(l<=mid)
build(p*2,l,mid);
if(r>mid)
build(p*2+1,mid+1,r);
up(p);
tr[p].tag2=1;
}
else
{
tr[p].lx=a[l].x;
tr[p].x=a[l].x;
tr[p].lm=a[l].x;
tr[p].m=a[l].x;
tr[p].lmi=a[l].x;
tr[p].mi=a[l].x;
tr[p].tag2=1;
}
}
inline void add(int p,int l,int r,long long x)
{
if(l<=tr[p].l&&tr[p].r<=r)
{
down(p);
if(tr[p].m+x<=rr&&tr[p].mi+x>=ll)
{
tr[p].tag1+=x;
tr[p].m+=x;
tr[p].mi+=x;
}
else if(tr[p].mi+x>=rr)
{
tr[p].m=rr;
tr[p].mi=rr;
tr[p].tag2=1;
tr[p].tag1=0;
tr[p].tag3=0;
tr[p].tag=rr;
}
else if(tr[p].m+x<=ll)
{
tr[p].m=ll;
tr[p].mi=ll;
tr[p].tag2=1;
tr[p].tag1=0;
tr[p].tag3=0;
tr[p].tag=ll;
}
else if(tr[p].l==tr[p].r)
{
tr[p].m+=x;
if(tr[p].m<ll)
tr[p].m=ll;
if(tr[p].m>rr)
tr[p].m=rr;
tr[p].mi=tr[p].m;
tr[p].tag1+=x;
if(tr[p].tag1<ll)
tr[p].tag1=ll;
if(tr[p].tag1>rr)
tr[p].tag1=rr;
}
else
{
int mid=(tr[p].l+tr[p].r)/2;
if(l<=mid)
add(p*2,l,r,x);
if(r>mid)
add(p*2+1,l,r,x);
up(p);
}
}
else
{
down(p);
int mid=(tr[p].l+tr[p].r)/2;
if(l<=mid)
add(p*2,l,r,x);
if(r>mid)
add(p*2+1,l,r,x);
up(p);
}
}
inline void exadd(int p,int l,int r,long long x)
{
if(l<=tr[p].l&&tr[p].r<=r)
{
down(p);
if(tr[p].m*x<=rr)
{
down(p);
tr[p].tag2*=x;
tr[p].m*=x;
tr[p].mi*=x;
}
else if(tr[p].mi*x>=rr)
{
tr[p].m=rr;
tr[p].mi=rr;
tr[p].tag2=1;
tr[p].tag1=0;
tr[p].tag3=0;
tr[p].tag=rr;
}
else if(tr[p].l==tr[p].r)
{
tr[p].m*=x;
if(tr[p].m<ll)
tr[p].m=ll;
if(tr[p].m>rr)
tr[p].m=rr;
tr[p].mi=tr[p].m;
tr[p].tag2*=x;
if(tr[p].tag2>rr)
tr[p].tag2=rr;
}
else
{
int mid=(tr[p].l+tr[p].r)/2;
if(l<=mid)
exadd(p*2,l,r,x);
if(r>mid)
exadd(p*2+1,l,r,x);
up(p);
}
}
else
{
down(p);
int mid=(tr[p].l+tr[p].r)/2;
if(l<=mid)
exadd(p*2,l,r,x);
if(r>mid)
exadd(p*2+1,l,r,x);
up(p);
}
}
inline void change(int p,int l,int r,long long x)
{
if(l<=tr[p].l&&tr[p].r<=r)
{
down(p);
if(tr[p].m+tr[p].lm*x<=rr)
{
tr[p].tag3+=x;
tr[p].m+=tr[p].lm*x;
tr[p].mi+=tr[p].lmi*x;
}
else if(tr[p].mi+tr[p].lmi*x>=rr)
{
tr[p].m=rr;
tr[p].mi=rr;
tr[p].tag2=1;
tr[p].tag1=0;
tr[p].tag3=0;
tr[p].tag=rr;
}
else if(tr[p].l==tr[p].r)
{
tr[p].m+=tr[p].lm*x;
if(tr[p].m<ll)
tr[p].m=ll;
if(tr[p].m>rr)
tr[p].m=rr;
tr[p].mi=tr[p].m;
tr[p].tag3+=x;
if(tr[p].tag3>rr)
tr[p].tag3=rr;
}
else
{
int mid=(tr[p].l+tr[p].r)/2;
if(l<=mid)
change(p*2,l,r,x);
if(r>mid)
change(p*2+1,l,r,x);
up(p);
}
}
else
{
down(p);
int mid=(tr[p].l+tr[p].r)/2;
if(l<=mid)
change(p*2,l,r,x);
if(r>mid)
change(p*2+1,l,r,x);
up(p);
}
}
inline long long find(int p,int l,int r)
{
if(tr[p].l==l&&tr[p].r==r)
return tr[p].m;
else
{
down(p);
int mid=(tr[p].l+tr[p].r)/2;
if(l<=mid)
return find(p*2,l,r);
if(r>mid)
return find(p*2+1,l,r);
}
}
int main()
{
int n;
scanf("%d%d%d",&n,&ll,&rr);
int i;
char x[10];
for(i=1;i<=n;i++)
{
scanf("%s",x);
if(x[0]=='+')
ask[i].p=1;
else if(x[0]=='-')
ask[i].p=2;
else if(x[0]=='*')
ask[i].p=3;
else if(x[0]=='@')
ask[i].p=4;
scanf("%d",&ask[i].x);
}
int q;
scanf("%d",&q);
for(i=1;i<=q;i++)
{
scanf("%d",&a[i].x);
a[i].t=i;
}
sort(a+1,a+1+q);
for(i=1;i<=q;i++)
fx[a[i].t]=i;
build(1,1,q);
for(i=1;i<=n;i++)
{
/*for(int j=1;j<=5;j++)
printf("%d %d %lld %lld %lld %lld\n",tr[j].l,tr[j].r,tr[j].m,tr[j].mi,tr[j].tag,tr[j].tag1);
printf("\n");*/
if(ask[i].p==1)
add(1,1,q,ask[i].x);
else if(ask[i].p==2)
add(1,1,q,-ask[i].x);
else if(ask[i].p==3)
exadd(1,1,q,ask[i].x);
else if(ask[i].p==4)
change(1,1,q,ask[i].x);
}
/* for(int j=1;j<=5;j++)
printf("%d %d %lld %lld %lld %lld\n",tr[j].l,tr[j].r,tr[j].m,tr[j].mi,tr[j].tag,tr[j].tag1);*/
for(i=1;i<=q;i++)
printf("%lld\n",find(1,fx[i],fx[i]));
return 0;
}