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--游标与链式查找
一:游标 [能不用游标的地方就不要用游标,它是占用数据库资源的] find操作是返回一个游标,为了方便我们查看结果,mongodb shell会自动迭代结果.[游标也是递增的] 2.迭代结果的两种方式 ...
- Linux控制台版本号2048
在Github上看到一个荷兰人写的linux控制台版的2048,用的C语言.感觉非常有意思. 原网址在这里. 读了一下他的源代码,感觉写的不错.就厚着脸皮加了一些中文凝视,源代码例如以下: /* == ...
- [cocos2dx笔记012]一定简易的UI配置类
使用cocostudio能够装载编辑好的UI,可是过于复杂.特别是在加截UI后,发现触屏事件有些问题. 假设直接使用程序写死载入UI又过于麻烦.花点时间,添加了一个基于ini的UI配置类,眼下仅仅实现 ...
- 翻译Beginning iOS 7 Development中文版
不会iOS开发好像真的说只是去,来本中文版的Beginning iOS 7 Development吧. 看了Beginning iOS 7 Development这本书,感觉蛮不错的.全英文的,没有中 ...
- 2016.04.25,英语,《Vocabulary Builder》Unit 18
capit, from the Latin word for 'head', caput ['keɪpət] n.头,首 , turns up in some pretty important pla ...
- 扩展函数之 IsWhat 简单好用
代码实现: /***扩展函数名细***/ //[IsInRange] ; //以前写法 & num < ) { } //现在写法 , )) { } //datetime类型也支持 //[ ...
- hdoj--1829--A Bug's Life(带权并查集)
A Bug's Life Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- poj1028--动态规划--Ignatius and the Princess III
Ignatius and the Princess III Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ...
- nyoj--44--子串和(动态规划)
子串和 时间限制:5000 ms | 内存限制:65535 KB 难度:3 描述 给定一整型数列{a1,a2...,an},找出连续非空子串{ax,ax+1,...,ay},使得该子序列的和最大, ...
- Wannafly挑战赛25 B 面积并 数学
题面 题意:有一个正n边形,它的外接圆的圆心位于原点,半径为l .以原点为圆心,r为半径作一个圆,求圆和这个正n边形的面积并.3<=n<=1e8 1<=l<=1e6 0< ...