首页 > 其他分享 >[AHOI2014/JSOI2014]奇怪的计算器

[AHOI2014/JSOI2014]奇怪的计算器

时间:2022-12-14 21:02:54浏览次数:50  
标签:return AHOI2014 tree mid long maxdata 计算器 JSOI2014 mindata

链接:https://www.luogu.com.cn/problem/P4041 题目描述:给定一个数列$a$,与常数$L$,$R$,实现下列四个操作: 1.将所有数加$d$。 2.将所有数减$d$。 3.将所有数乘$d$。 4.将所有数加上初始值的$d$倍。 规定每一次操作完后,要将小于$L$的数置为$L$,大于$L$的数置为$R$,求$q$此操作后的序列。 题解:若将$a$排序,我们可以发现,在操作的过程中序列始终单调不降,此时我们可以通过二分来确定要变为$L$的与要变为$R$的数的范围。这样,我们要实现的其实还有第五个操作:将$[l,r]$置为$x$。 这个可以直接用线段树维护,但这样直接维护的代码量却不小。我就写了$250$多行代码,$30$分一直调不出。 此时,你要用到一个神奇的方法,将所有的修改操作看作将$a_{i}$置为$A\times a_{i}+b\times x_{i}+c$,这样就把所有的操作合并了,就只用维护一个操作了,你会发现代码量会减少很多。 但这样任然过不了$BZOJ$的数据,我们可以将二分的过程改为线段树二分,复杂度就优化到$O(n log n)$了。 ``` #include #include #include using namespace std; struct node { long long num,data; bool operator < (const node &a)const { return data<a.data; }="" };="" node="" delta[2000001];="" struct="" seg="" {="" long="" l,r;="" mindata,maxdata,lazya,lazyb,lazyc;="" l,r,n,ans[2000001];="" tree[2000001];="" inline="" void="" spread(register="" int="" k)="" tree[k*2].lazya*="tree[k].lazyA;" tree[k*2].lazyb="tree[k*2].lazyB*tree[k].lazyA+tree[k].lazyB;" tree[k*2].lazyc="tree[k*2].lazyC*tree[k].lazyA+tree[k].lazyC;" tree[k*2].mindata="tree[k*2].mindata*tree[k].lazyA+delta[tree[k*2].l].data*tree[k].lazyB+tree[k].lazyC;" tree[k*2].maxdata="tree[k*2].maxdata*tree[k].lazyA+delta[tree[k*2].r].data*tree[k].lazyB+tree[k].lazyC;" tree[k*2+1].lazya*="tree[k].lazyA;" tree[k*2+1].lazyb="tree[k*2+1].lazyB*tree[k].lazyA+tree[k].lazyB;" tree[k*2+1].lazyc="tree[k*2+1].lazyC*tree[k].lazyA+tree[k].lazyC;" tree[k*2+1].mindata="tree[k*2+1].mindata*tree[k].lazyA+delta[tree[k*2+1].l].data*tree[k].lazyB+tree[k].lazyC;" tree[k*2+1].maxdata="tree[k*2+1].maxdata*tree[k].lazyA+delta[tree[k*2+1].r].data*tree[k].lazyB+tree[k].lazyC;" tree[k].lazya="1;" tree[k].lazyb="tree[k].lazyC=0;" return;="" build(register="" k,register="" l,register="" r)="" tree[k].l="l;" tree[k].r="r;" mid="(l+r)/2;" if="" (l="=r)" tree[k].mindata="tree[k].maxdata=delta[l].data;" build(k*2,l,mid);="" build(k*2+1,mid+1,r);="" tree[k].maxdata="tree[k*2+1].maxdata;" add(register="" r,register="" a,register="" b,register="" c)="" (tree[k].l="=l&&tree[k].r==r)" tree[k].lazya*="a;" tree[k].lazyc="tree[k].lazyC*a+c;" spread(k);="" (l<="mid&&r<=mid)" add(k*2,l,r,a,b,c);="">=mid+1&&r>=mid+1) { add(k*2+1,l,r,a,b,c); tree[k].mindata=tree[k*2].mindata; tree[k].maxdata=tree[k*2+1].maxdata; return; } add(k*2,l,mid,a,b,c); add(k*2+1,mid+1,r,a,b,c); tree[k].mindata=tree[k*2].mindata; tree[k].maxdata=tree[k*2+1].maxdata; return; } inline long long query(register int k,register int x) { if (tree[k].l==tree[k].r) return tree[k].mindata; spread(k); int mid=(tree[k].l+tree[k].r)/2; if (x<=mid) return query(k*2,x); else return query(k*2+1,x); } char ot1[1000001]; long long ot2[1000001]; inline int read() { register char c=0; register int sum=0; while (c<'0'||c>'9') c=getchar(); while ('0'<=c&&c<='9') { sum=sum*10+c-'0'; c=getchar(); } return sum; } inline void write(register int x) { if (x==0) return; write(x/10); putchar(x%10+'0'); return; } inline int min_segment_search(register int k,register int l,register int r,register int d) { if (tree[k].l==tree[k].r) { if (tree[k].mindata<=d) return n+1; return tree[k].l; } spread(k); int mid=(tree[k].l+tree[k].r)/2; if (tree[k*2+1].mindata>d&&l<=mid) return min(min_segment_search(k*2,l,mid,d),mid+1); else return min_segment_search(k*2+1,mid+1,r,d); } inline int max_segment_search(register int k,register int l,register int r,register int d) { if (tree[k].l==tree[k].r) { if (tree[k].maxdata>=d) return 0; return tree[k].l; } spread(k); int mid=(tree[k].l+tree[k].r)/2; if (tree[k*2].maxdata

标签:return,AHOI2014,tree,mid,long,maxdata,计算器,JSOI2014,mindata
From: https://www.cnblogs.com/zhouhuanyi/p/16983515.html

相关文章

  • [AHOI2014/JSOI2014]拼图
    链接:https://www.luogu.com.cn/problem/P4039题目描述:有一些长为$n$,宽为$w_{i}$的黑白色矩形,要将它们拼成一个$n\timesm$的大矩形,求大矩形中最大的全白子矩形的面积的......
  • [JSOI2014]支线剧情2
    链接:https://vjudge.net/problem/HYSBZ-5031题目描述:给定一个树形图,规定一号点为根节点。到达一个点时可以进行下列操作:$1$.沿着一条有向边走到下一个节点。$2$.回到......
  • [AHOI2014/JSOI2014]骑士游戏
    链接:https://www.luogu.com.cn/problem/P4042题目描述:对于一个怪物$i$,可以花费$c_{i}$的代价将其变为一个怪物集合,或花费$c2_{i}$的代价消灭他。求消灭怪物$1$的最小代......
  • JAVA学到方法写了一个四则运算计算器,请教一下有什么需要改进的
    packagemethod;/**四则运算计算器**/importjava.util.Scanner;publicclassDemo07{publicstaticvoidmain(String[]args){Scanners......
  • MFC,VC++计算器小程序
    大学期末没课,某个中午闲来无聊,正好在自学MFC,于是想用MFC、C++写点东西,由于能力有限,当然的写个简单点的啦,于是花了两个小时写了这个计算器的小程序,希望对初学VC++和MFC的朋友有所帮助。程......
  • 一、Qt初尝试,做一个QT计算器《QT 入门到实战》
    学习目标了解qt的基本信息了解qt的下载及安装了解创建一个基本qt项目的流程了解信号与槽通过示例了解信号与槽的设置与编写了解控件添加的方式了解控件如何使......
  • 直播系统app源码,自定义九宫格,计算器布局,验证码认证
    直播系统app源码,自定义九宫格,计算器布局,验证码认证1、先写几个接收验证码的文本框 returnScaffold(   backgroundColor:ColorsUtil.hexStringColor("#B1B1B1")......
  • 逆波兰计算器-栈
    java.util.Stack;/**@PROJECT_NAME:DataStruct@DESCRIPTION:@USER:28416@DATE:2022/11/3014:41逆波兰表达式*/publicclassPolandNotation{publi......
  • C#-简易公式计算器代码实现
    计算器如图所示,仅实现加减乘除及括号功能,公式错误时会有提示。首先建立一个inputList,每点击数据一下,便将内容添加至inputList中,点击后退时则删除List中最后一个元素。......
  • 教你用Python制作BMI计算器
    案例介绍欢迎来到我的小院,我是霍大侠,恭喜你今天又要进步一点点了!我们来用Python相关知识,做一个BMI计算器的案例。你可以通过控制台的提示信息,输入身高和体重,注意单位,系......