BZOJ 3878 [AHOI&JSOI2014]奇怪的计算器 (线段树)
线段树好题
题目保证$a$一定是正整数,容易发现计算结果是单调的
我们把询问离线,并按照从小到大排序
某次操作可能导致某些位置达到边界$L/R$
根据单调性的结论
这些位置一定是从$1$向右扩展或者$Q$向左扩展
可以二分找到这个区间,然后区间覆盖
那么修改操作,归根结底是这$4$种操作:
1.区间加减 2.区间乘法 3.区间覆盖 4.区间每个位置加某个数*对应位置的固定权值
比较复杂,考虑抽象化这个问题,把它写成一个函数
$f(a,b,c)=a*f(a,b,c)+b*X_{i}+c$
上述四种操作变成
$1.f(1,0,x) 2.(x,0,0) 3.(0,0,x) 4.(1,x,0)$
我们只需要每次把值往里面带,然后用线段树维护这个函数就行了
注意下推标记的顺序
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #define N1 100010
- #define ll long long
- using namespace std;
- int gint()
- {
- int ret=,fh=; char c=getchar();
- while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
- while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
- return ret*fh;
- }
- int n;
- ll ml,mr;
- struct node{int id,x;ll ans;}q[N1];
- int cmp1(node s1,node s2){return s1.x<s2.x;}
- int cmp2(node s1,node s2){return s1.id<s2.id;}
- int v[N1],p[N1],f[N1],m;
- struct SEG{
- #define M1 (N1<<2)
- ll mi[M1],ma[M1],a[M1],b[M1],c[M1];
- void pushup(int rt)
- {
- mi[rt]=mi[rt<<];
- ma[rt]=ma[rt<<|];
- }
- void pushdown(int l,int r,int rt)
- {
- int mid=(l+r)>>;
- if(a[rt]==&&!b[rt]&&!c[rt]) return;
- a[rt<<]=a[rt]*a[rt<<];
- a[rt<<|]=a[rt]*a[rt<<|];
- b[rt<<]=a[rt]*b[rt<<]+b[rt];
- b[rt<<|]=a[rt]*b[rt<<|]+b[rt];
- c[rt<<]=a[rt]*c[rt<<]+c[rt];
- c[rt<<|]=a[rt]*c[rt<<|]+c[rt];
- mi[rt<<]=a[rt]*mi[rt<<]+b[rt]*v[l]+c[rt];
- mi[rt<<|]=a[rt]*mi[rt<<|]+b[rt]*v[mid+]+c[rt];
- ma[rt<<]=a[rt]*ma[rt<<]+b[rt]*v[mid]+c[rt];
- ma[rt<<|]=a[rt]*ma[rt<<|]+b[rt]*v[r]+c[rt];
- a[rt]=; b[rt]=c[rt]=;
- }
- void update(int L,int R,int l,int r,int rt,ll A,ll B,ll C)
- {
- if(L<=l&&r<=R)
- {
- a[rt]=A*a[rt];
- b[rt]=A*b[rt]+B;
- c[rt]=A*c[rt]+C;
- mi[rt]=A*mi[rt]+B*v[l]+C;
- ma[rt]=A*ma[rt]+B*v[r]+C;
- return;
- }
- int mid=(l+r)>>;
- if(L<=mid) update(L,R,l,mid,rt<<,A,B,C);
- if(R>mid) update(L,R,mid+,r,rt<<|,A,B,C);
- pushup(rt);
- }
- ll calc1(int x,ll rt,ll A,ll B,ll C){return A*mi[rt]+B*v[x]+C;}
- ll calc2(int x,ll rt,ll A,ll B,ll C){return A*ma[rt]+B*v[x]+C;}
- ll de;
- int qleft(int l,int r,int rt,int A,int B,int C)
- {
- if(l==r){ if(calc2(r,rt,A,B,C)>ml) return l-; return l; }
- int mid=(l+r)>>; pushdown(l,r,rt); de=calc2(mid,rt<<,A,B,C);
- if(calc2(mid,rt<<,A,B,C)<=ml) return qleft(mid+,r,rt<<|,A,B,C);
- else return qleft(l,mid,rt<<,A,B,C);
- }
- int qright(int l,int r,int rt,int A,int B,int C)
- {
- if(l==r){ if(calc1(l,rt,A,B,C)<mr) return l+; return l; }
- int mid=(l+r)>>; pushdown(l,r,rt); de=calc1(mid+,rt<<|,A,B,C);
- if(calc1(mid+,rt<<|,A,B,C)>=mr) return qright(l,mid,rt<<,A,B,C);
- else return qright(mid+,r,rt<<|,A,B,C);
- }
- void build(int l,int r,int rt)
- {
- a[rt]=; b[rt]=c[rt]=;
- if(l==r){ mi[rt]=ma[rt]=v[l]; return; }
- int mid=(l+r)>>;
- build(l,mid,rt<<);
- build(mid+,r,rt<<|);
- pushup(rt);
- }
- void print(int l,int r,int rt,node *s)
- {
- if(l==r){ s[l].ans=mi[rt]; return; }
- int mid=(l+r)>>; pushdown(l,r,rt);
- print(l,mid,rt<<,s);
- print(mid+,r,rt<<|,s);
- }
- ll query(int x,int l,int r,int rt)
- {
- if(l==r) return mi[rt];
- int mid=(l+r)>>; pushdown(l,r,rt);
- if(x<=mid) return query(x,l,mid,rt<<);
- else return query(x,mid+,r,rt<<|);
- }
- }s;
- int main()
- {
- scanf("%d%lld%lld",&n,&ml,&mr);
- char str[]; int i,j,l,r;
- for(i=;i<=n;i++)
- {
- scanf("%s",str);
- switch(str[])
- {
- case '+': p[i]=; break;
- case '-': p[i]=; break;
- case '*': p[i]=; break;
- case '@': p[i]=; break;
- }
- f[i]=gint();
- }
- scanf("%d",&m);
- for(i=;i<=m;i++) q[i].x=gint(),q[i].id=i;
- sort(q+,q+m+,cmp1);
- for(i=;i<=m;i++) v[i]=q[i].x;
- s.build(,m,);
- s.query(,,m,);
- for(i=;i<=n;i++)
- {
- switch(p[i])
- {
- case :
- {
- l=s.qright(,m,,,,f[i]),r=m;
- if(l>) s.update(,l-,,m,,,,f[i]);
- if(l<=r) s.update(l,r,,m,,,,mr);
- break;
- }
- case :
- {
- l=s.qleft(,m,,,,-f[i]),r=m;
- if(l>) s.update(,l,,m,,,,ml);
- if(l<r) s.update(l+,r,,m,,,,-f[i]);
- break;
- }
- case :
- {
- l=s.qright(,m,,f[i],,),r=m;
- if(l>) s.update(,l-,,m,,f[i],,);
- if(l<=r) s.update(l,r,,m,,,,mr);
- break;
- }
- case :
- {
- l=s.qright(,m,,,f[i],),r=m;
- if(l>) s.update(,l-,,m,,,f[i],);
- if(l<=r) s.update(l,r,,m,,,,mr);
- break;
- }
- }
- }
- s.print(,m,,q);
- sort(q+,q+m+,cmp2);
- for(i=;i<=m;i++) printf("%lld\n",q[i].ans);
- return ;
- }
BZOJ 3878 [AHOI&JSOI2014]奇怪的计算器 (线段树)的更多相关文章
- BZOJ3878: [Ahoi2014&Jsoi2014]奇怪的计算器
BZOJ3878: [Ahoi2014&Jsoi2014]奇怪的计算器 Description [故事背景] JYY有个奇怪的计算器,有一天这个计算器坏了,JYY希望你能帮助他写 一个程序来模 ...
- [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+并查集+启发式合并)
[BZOJ 3123] [SDOI 2013]森林(可持久化线段树+启发式合并) 题面 给出一个n个节点m条边的森林,每个节点都有一个权值.有两种操作: Q x y k查询点x到点y路径上所有的权值中 ...
- 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.5110.[CodePlus2017]Yazid 的新生舞会(线段树/树状数组/分治)
LOJ BZOJ 洛谷 又来发良心题解啦 \(Description\) 给定一个序列\(A_i\).求有多少个子区间,满足该区间众数出现次数大于区间长度的一半. \(n\leq5\times10^5 ...
- BZOJ.2653.[国家集训队]middle(可持久化线段树 二分)
BZOJ 洛谷 求中位数除了\(sort\)还有什么方法?二分一个数\(x\),把\(<x\)的数全设成\(-1\),\(\geq x\)的数设成\(1\),判断序列和是否非负. 对于询问\(( ...
- BZOJ 5168 && Luogu P3740 [HAOI2014]贴海报 线段树~~
据说某谷数据十分水...但幸好BZOJ上也过了...话说我记得讲课时讲的是奇奇怪怪的离散化..但现在突然觉得什么都可以线段树瞎搞了...QAQ 直接就是这个区间有没有被覆盖,被覆盖直接return: ...
- BZOJ 3307 雨天的尾巴 (树上差分+线段树合并)
题目大意:给你一棵树,树上一共n个节点,共m次操作,每次操作给一条链上的所有节点分配一个权值,求所有节点被分配到所有的权值里,出现次数最多的权值是多少,如果出现次数相同就输出最小的. (我辣鸡bzoj ...
- [AHOI 2009] 维护序列(线段树模板题)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...
随机推荐
- mongodb-主从复制
1 主从复制: 一个概念,在sqlserver或者说是mysql也有 2 主从复制解决了哪些问题??? 读写压力:以前是一个mongodb去承载海量的读和写,这样的话终有瓶颈的.使用一主多从, 从服务 ...
- POJ 3528
三维凸包 /* 增量法求凸包.选取一个四面体,同时把它各面的方向向量向外,增加一个点时,若该点与凸包上的某些面的方 向向量在同一侧,则去掉那些面,并使某些边与新增点一起连成新的凸包上的面. */ #i ...
- 【VC编程技巧】窗口☞3.6以渐变效果加载对话框
平时我们常常能够看到非常多应用程序启动过程非常酷.什么百叶窗.渐变,各种效果,今天我们看一下怎样在程序中添加这样的效果. 一.演示样例展示: watermark/2/text/aHR0cDovL2Js ...
- WAS_集群部署应用遭遇ADMA0085E和ADMA0109W错误
原创作品,出自 "深蓝的blog" 博客.深蓝的blog:http://blog.csdn.net/huangyanlong/article/details/47143431 近日 ...
- andoid电阻触摸移植
这里我使用的是210的开发板 系统Android4.0.4 内核linux3.0.8 要用电阻屏一般都是使用tslib进行校准的 这里给个我在android上用的tslib 下载地址 http://d ...
- springAOP注解方式实现日志操作
通过自定义注解调用方法执行日志存储: package com.zktx.platform.log2; import java.lang.reflect.Method; import java.util ...
- Adding a model
https://docs.asp.net/en/latest/tutorials/first-mvc-app/adding-model.html Adding data model classes I ...
- 饭卡(hdoj--2546--背包)
饭卡 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...
- HUdson2092整数解
2019-05-17 16:04:37 加油,坚持就是胜利,fightting m / i的情况,i可能等于0 #include <bits/stdc++.h> using namespa ...
- logging (日志) 模块
本文源自景女神 函数式简单配置 import logging logging.debug('debug message') logging.info('info message') logging.w ...