[Ahoi2014]奇怪的计算器 解题报告
来源:互联网 发布:volt模板引擎 php 编辑:程序博客网 时间:2024/06/05 06:51
感觉这是一道非常好的题,不过我看几乎所有人都是把它当傻逼题写的,为出题人感到遗憾。
一个很简单的性质是无论如何操作,每个数的相对大小是不变的,所以我们每次改变的都是一个区间。所以我们维护一个标记
但是这个题的关键是
这个其实是在
这是因为虽然
唯一需要long long的地方只在于找到>R的非法区间,其他的变量其实我们都用int,令其自然溢出即可。
#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,rvoid 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); fread(cp,1,3000000,stdin); 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);}
总结:
①一定要算好量的范围!!
②对于中间量可能很大,结果量很小的情况,我们可以在模意义下去运算它。——参考
0 0
- [Ahoi2014]奇怪的计算器 解题报告
- bzoj3878 [Ahoi2014]奇怪的计算器
- bzoj 3878: [Ahoi2014]奇怪的计算器
- 【线段树】[BZOJ3787][AHOI2014]奇怪的计算器
- 【BZOJ3878】[Ahoi2014]奇怪的计算器【线段树】
- 【bzoj3878】【AHOI2014】【奇怪的计算器】【线段树】
- BZOJ3878 [Ahoi2014]奇怪的计算器 线段树
- [题解]bzoj3878 AHOI2014 奇怪的计算器
- BZOJ 3878 Ahoi2014 奇怪的计算器 线段树
- 【BZOJ3878】【Ahoi2014】奇怪的计算器 维护区间性质。线段树
- 2833 奇怪的梦境 【解题报告】
- 百度的科学计算器(解题报告)
- [解题报告]计算器
- 奇怪的电梯解题报告(广度优先搜索)
- [bzoj3878]奇怪的计算器
- csu1655 文本计算器 与 hdu1237 简单计算器 解题报告
- 某人的解题报告
- ZOJ1002的解题报告
- webkit webApp 开发技术要点总结
- 23种设计模式(15):备忘录模式
- ispunct字符串测试函数应用实例
- SpringMVC-处理模型数据
- update与delete多表联接问题
- [Ahoi2014]奇怪的计算器 解题报告
- 小知识点记录
- Seevlet注解
- 中断按键驱动程序
- 关于Android Studio第三方登录(使用QQ登录)代码
- search Paths $(SRCROOT)和$(PROJECT_DIR)区别
- building workspace has encountered
- 排序:归并排序
- VMware虚拟机错误提示:锁定文件失败 打不开磁盘 未能启动虚拟机