题面:BZOJ传送门 洛谷传送门

线段树好题

题目保证$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]奇怪的计算器 (线段树)的更多相关文章

  1. BZOJ3878: [Ahoi2014&Jsoi2014]奇怪的计算器

    BZOJ3878: [Ahoi2014&Jsoi2014]奇怪的计算器 Description [故事背景] JYY有个奇怪的计算器,有一天这个计算器坏了,JYY希望你能帮助他写 一个程序来模 ...

  2. [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+并查集+启发式合并)

    [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+启发式合并) 题面 给出一个n个节点m条边的森林,每个节点都有一个权值.有两种操作: Q x y k查询点x到点y路径上所有的权值中 ...

  3. 2018.07.25 bzoj3878: [Ahoi2014&Jsoi2014]奇怪的计算器(线段树)

    传送门 线段树综合. 让我想起一道叫做siano" role="presentation" style="position: relative;"&g ...

  4. AHOI2014/JSOI2014 奇怪的计算器

    题目描述 题解: 考虑到经过一系列变化后小数不可能比大数大,我们可以用线段树维护区间修改. 重点是,每个节点都可以通过$a[i]=a[i]*t1+a0[i]*t2+t3$这个函数来表示,我们就可以把三 ...

  5. BZOJ.5110.[CodePlus2017]Yazid 的新生舞会(线段树/树状数组/分治)

    LOJ BZOJ 洛谷 又来发良心题解啦 \(Description\) 给定一个序列\(A_i\).求有多少个子区间,满足该区间众数出现次数大于区间长度的一半. \(n\leq5\times10^5 ...

  6. BZOJ.2653.[国家集训队]middle(可持久化线段树 二分)

    BZOJ 洛谷 求中位数除了\(sort\)还有什么方法?二分一个数\(x\),把\(<x\)的数全设成\(-1\),\(\geq x\)的数设成\(1\),判断序列和是否非负. 对于询问\(( ...

  7. BZOJ 5168 && Luogu P3740 [HAOI2014]贴海报 线段树~~

    据说某谷数据十分水...但幸好BZOJ上也过了...话说我记得讲课时讲的是奇奇怪怪的离散化..但现在突然觉得什么都可以线段树瞎搞了...QAQ 直接就是这个区间有没有被覆盖,被覆盖直接return: ...

  8. BZOJ 3307 雨天的尾巴 (树上差分+线段树合并)

    题目大意:给你一棵树,树上一共n个节点,共m次操作,每次操作给一条链上的所有节点分配一个权值,求所有节点被分配到所有的权值里,出现次数最多的权值是多少,如果出现次数相同就输出最小的. (我辣鸡bzoj ...

  9. [AHOI 2009] 维护序列(线段树模板题)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...

随机推荐

  1. Spring深入理解(一)

    Spring 框架的设计理念与设计模式分析 Spring核心组件 Spring 框架中的核心组件只有三个:Core.Context 和 Beans Spring 的设计理念 前面介绍了 Spring ...

  2. 20160223.CCPP体系具体解释(0033天)

    程序片段(01):MyArray.h+MyArray.c+main.c 内容概要:数组库 ///MyArray.h #pragma once #define DT int//类型通用 typedef ...

  3. hdu 1239

    首先,p,q>=2,所以p,q<=50000; 然后,我们观察a<=b<1000,而p,q<=100000.那么,q>=10000时,p<=10,则a/b&l ...

  4. POJ3185 The Water Bowls 反转(开关)

    Description The cows have a line of 20 water bowls from which they drink. The bowls can be either ri ...

  5. java学习笔记(二)图形用户接口

    这个学期主要放在ACM比赛上去了,比赛结束了.不知不觉就15周了,这周就要java考试了,复习一下java吧.java的学习的目的还是让我们学以致用,让我们可以运用java开发一下小项目.而不是单单应 ...

  6. 2016.04.19,英语,《Vocabulary Builder》Unit 16

    top, comes from topos, the Greek word for 'place'. ectopic: [ek'tɑːpɪk] adj. [医]异位的,异常的 topical: ['t ...

  7. POJ3204 Ikki's Story - Road Reconstruction 网络流图的关键割边

    题目大意:一个有源有汇的城市,问最少增加城市中的多少道路可以增加源到汇上各个路径上可容纳的总车流量增加. 网络流关键割边集合指如果该边的容量增加,整个网络流图中的任意从原点到汇点的路径的流量便可增加. ...

  8. Mysql数据类型(二)

    字符类型 #官网:https://dev.mysql.com/doc/refman/5.7/en/char.html #注意:char和varchar括号内的参数指的都是字符的长度 #char类型:定 ...

  9. BZOJ 1196 二分+Kruskal

    思路: 二分答案 判一下能不能加 //By SirisuRen #include <cstdio> #include <cstring> #include <algori ...

  10. 由于找不到 opencv_world320.dll,无法继续执行代码

    首先找到自己软件安装(解压)的路径openCV (安装(解压)目录\opencv\build\x64\vc14\bin) 我的安装(解压)目录是:F:\OpenCV\Three320\opencv\b ...