称区间$[l,r]$的"信息"为其的答案和第一个、最后一个大于$x$的位置,显然通过$[l,mid]$和$[mid+1,r]$的信息可以$o(1)$合并得到$[l,r]$的信息

考虑分块,将其按$K$的块大小分块,区间查询时求出散块每一个位置的信息(将其看作一个区间)和每一个整块的信息,之后即可$o(K+\frac{n}{K})$合并得到整个块的信息

下面的问题即如何求整块的信息,对整块维护:1.排序后的结果;2.当$x$为块中每一个元素时的信息;3.[luogu6466]分散层叠算法的做法4所维护的分治结构(将$x$作为小于等于$x$的最大元素即可)

对于排序后的结果时间复杂度为$o(n\log n)-o(K)$(单点修改即插入排序),当得到排序后的结果后,该块的"信息"也可以在$o(K)$的复杂度内得到——

关于答案,只需要从小到大枚举元素,每一次即加入一个元素,通过链表支持合并即可

关于第一个和最后一个大于$x$的位置,维护排序后的序列位置的后缀最小值和最大值即可

由此即可支持单点修改,单次复杂度为$o(K)$,取$K=\sqrt{n}$单次复杂度即$o(\sqrt{n})$

时间复杂度为$o(n\log n)-o(\sqrt{n})$

(由于该oj似乎不支持提交,与某个通过的代码拍过,正确性大概是能保证的,速度大约是其1.5倍)

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 300005
4 #define K 600
5 #define D 3
6 #define ll long long
7 #define L (k<<1)
8 #define R (L+1)
9 #define mid (l+r>>1)
10 struct Data{
11 int l,r;
12 ll ans;
13 }ans[N];
14 int n,m,k,p,x,y,z,num[21],a[N],bl[N],st[K],ed[K],id[N];
15 int read(){
16 int x=0;
17 char c=getchar();
18 while ((c<'0')||(c>'9'))c=getchar();
19 while ((c>='0')&&(c<='9')){
20 x=x*10+(c-'0');
21 c=getchar();
22 }
23 return x;
24 }
25 void write(ll x,char c='\0'){
26 while (x){
27 num[++num[0]]=x%10;
28 x/=10;
29 }
30 if (!num[0])putchar('0');
31 while (num[0])putchar(num[num[0]--]+'0');
32 putchar(c);
33 }
34 bool cmp(int x,int y){
35 return a[x]<a[y];
36 }
37 bool Cmp(int x,int y){
38 return a[x]<=y;
39 }
40 Data merge(Data x,Data y);
41 namespace Rope{
42 int n,vis[N],l[N],r[N];
43 ll ans;
44 void init(int nn){
45 n=nn;
46 for(int i=0;i<=n+1;i++)vis[i]=0;
47 for(int i=1;i<=n;i++)l[i]=r[i]=i;
48 }
49 void link(int x){
50 ans+=(ll)(x-l[x]+1)*(r[x+1]-x);
51 l[r[x+1]]=l[x],r[l[x]]=r[x+1];
52 }
53 ll add(int x){
54 ans=vis[x]=1;
55 if (vis[x-1])link(x-1);
56 if (vis[x+1])link(x);
57 return ans;
58 }
59 };
60 namespace Seg{
61 int Pos[2],b[K<<2][K],pos[K<<2][K][2];
62 void get(int k,int x){
63 b[k][0]=0;
64 for(int i=st[x];i<=ed[x];i++)b[k][++b[k][0]]=id[i];
65 }
66 void up(int k){
67 b[k][0]=0;
68 int x=1,y=1;
69 while ((x<=b[L][0])||(y<=b[R][0])){
70 if ((x<=b[L][0])&&((y>b[R][0])||(cmp(b[L][x],b[R][y])))){
71 b[k][++b[k][0]]=b[L][x];
72 pos[k][b[k][0]][0]=x;
73 pos[k][b[k][0]][1]=0;
74 x+=D;
75 }
76 else{
77 b[k][++b[k][0]]=b[R][y];
78 pos[k][b[k][0]][0]=0;
79 pos[k][b[k][0]][1]=y;
80 y+=D;
81 }
82 }
83 memset(Pos,0,sizeof(Pos));
84 for(int i=1;i<=b[k][0];i++)
85 for(int p=0;p<2;p++){
86 if (pos[k][i][p])Pos[p]=pos[k][i][p];
87 pos[k][i][p]=Pos[p];
88 }
89 }
90 void build(int k,int l,int r){
91 if (l==r){
92 get(k,l);
93 return;
94 }
95 build(L,l,mid);
96 build(R,mid+1,r);
97 up(k);
98 }
99 void update_point(int k,int l,int r,int x){
100 if (l==r){
101 get(k,x);
102 return;
103 }
104 if (x<=mid)update_point(L,l,mid,x);
105 else update_point(R,mid+1,r,x);
106 up(k);
107 }
108 void query_seg(int k,int l,int r,int x,int y,int z,int w){
109 if ((l>y)||(x>r))return;
110 if (!z){
111 ans[0]=merge(ans[0],Data{0,0,0});
112 return;
113 }
114 if (l==r){
115 ans[0]=merge(ans[0],ans[b[k][z]]);
116 return;
117 }
118 int zl=pos[k][z][0],zr=pos[k][z][1];
119 while ((zl<b[L][0])&&(Cmp(b[L][zl+1],w)))zl++;
120 while ((zr<b[R][0])&&(Cmp(b[R][zr+1],w)))zr++;
121 query_seg(L,l,mid,x,y,zl,w);
122 query_seg(R,mid+1,r,x,y,zr,w);
123 }
124 void query(int l,int r,int x){
125 if (l>r)return;
126 query_seg(1,1,bl[n],l,r,lower_bound(b[1]+1,b[1]+b[1][0]+1,x,Cmp)-b[1]-1,x);
127 }
128 };
129 Data merge(Data x,Data y){
130 Data ans;
131 ans.ans=x.ans+y.ans;
132 if ((x.r<0)&&(y.r<0)){
133 ans.l=x.l+y.l,ans.r=-1;
134 ans.ans+=(ll)x.l*y.l;
135 return ans;
136 }
137 if (x.r<0){
138 ans.l=x.l+y.l,ans.r=y.r;
139 ans.ans+=(ll)x.l*y.l;
140 return ans;
141 }
142 if (y.r<0){
143 ans.l=x.l,ans.r=x.r+y.l;
144 ans.ans+=(ll)x.r*y.l;
145 return ans;
146 }
147 ans.l=x.l,ans.r=y.r;
148 ans.ans+=(ll)x.r*y.l;
149 return ans;
150 }
151 void upd(int k,int x){
152 for(int i=st[k];i<=ed[k];i++)
153 if (id[i]==x){
154 x=i;
155 break;
156 }
157 int s=id[x];
158 for(int i=x;i<ed[k];i++)id[i]=id[i+1];
159 for(int i=st[k];i<ed[k];i++)
160 if (cmp(s,id[i])){
161 for(int j=ed[k];j>i;j--)id[j]=id[j-1];
162 id[i]=s;
163 return;
164 }
165 id[ed[k]]=s;
166 }
167 void calc(int k){
168 ans[id[ed[k]]].l=ed[k]-st[k]+1,ans[id[ed[k]]].r=-1;
169 int l=id[ed[k]]-st[k],r=ed[k]-id[ed[k]];
170 for(int i=ed[k]-1;i>=st[k];i--){
171 ans[id[i]].l=l,ans[id[i]].r=r;
172 l=min(l,id[i]-st[k]),r=min(r,ed[k]-id[i]);
173 }
174 Rope::init(ed[k]-st[k]+1);
175 ll sum=0;
176 for(int i=st[k];i<=ed[k];i++){
177 sum+=Rope::add(id[i]-st[k]+1);
178 ans[id[i]].ans=sum;
179 }
180 }
181 int main(){
182 n=read(),m=read(),k=(int)sqrt(n);
183 for(int i=1;i<=n;i++)a[i]=read();
184 for(int i=1;i<=n;i++){
185 id[i]=i;
186 bl[i]=(i-1)/k+1;
187 if (!st[bl[i]])st[bl[i]]=i;
188 ed[bl[i]]=i;
189 }
190 for(int i=1;i<=bl[n];i++){
191 sort(id+st[i],id+ed[i]+1,cmp);
192 calc(i);
193 }
194 Seg::build(1,1,bl[n]);
195 for(int i=1;i<=m;i++){
196 p=read(),x=read(),y=read();
197 if (p==1){
198 a[x]=y;
199 upd(bl[x],x);
200 calc(bl[x]);
201 Seg::update_point(1,1,bl[n],bl[x]);
202 }
203 else{
204 z=read();
205 ans[0]=Data{0,-1,0};
206 if (bl[x]==bl[y]){
207 for(int j=x;j<=y;j++)
208 if (a[j]>z)ans[0]=merge(ans[0],Data{0,0,0});
209 else ans[0]=merge(ans[0],Data{1,-1,1});
210 }
211 else{
212 for(int j=x;j<=ed[bl[x]];j++)
213 if (a[j]>z)ans[0]=merge(ans[0],Data{0,0,0});
214 else ans[0]=merge(ans[0],Data{1,-1,1});
215 Seg::query(bl[x]+1,bl[y]-1,z);
216 for(int j=st[bl[y]];j<=y;j++)
217 if (a[j]>z)ans[0]=merge(ans[0],Data{0,0,0});
218 else ans[0]=merge(ans[0],Data{1,-1,1});
219 }
220 write(ans[0].ans,'\n');
221 }
222 }
223 return 0;
224 }

[Comet1173]最简单的题的更多相关文章

  1. 2019浙大校赛--A--Thanks, TuSimple!(简单模拟题)

    这题前三段都是一堆吹爆赞助商的屁话,正式题目在图片下边,一个简单模拟题. 题目大意: 有n个男生,m个女生在进行舞会,其中一部分男生祥和比自己矮的女生跳舞,一部分男生想和比自己高的女生跳舞,一部分女生 ...

  2. 简单数据结构题(from 钟子谦——IOI2018集训队自选题)

    简单数据结构题(from 钟子谦--IOI2018集训队自选题) 试题描述 给一棵 \(n\) 个点的树,点权开始为 \(0\) ,有 \(q\) 次操作,每次操作是选择一个点,把周围一圈点点权 \( ...

  3. java算法题每日一练01,java入门简单算法题小练

    1.给数组做反序 public class Ak01 { public static void main(String[] args) { int[] a = new int[]{22,48,41,2 ...

  4. 一个简单算法题引发的思考<DNA sorting>(about cin/template/new etc)

    首先是昨天在北京大学oj网上看到一个简单的算法题目,虽然简单,但是如何完成一段高效.简洁.让人容易看懂的代码对于我这个基础不好,刚刚进入计算机行业的小白来说还是有意义的.而且在写代码的过程中,会发现自 ...

  5. UVa 679 小球下落 简单模拟题,树

    题目大意:给你一个完全二叉树,并且给他们编号,编号规则为左子树为2*k,右子树为2*k+1,每一个节点 上都有一个开关,初始时开关都处于关闭状态,小球碰到节点就会改变该点的开关的状态.然后给你I个小球 ...

  6. 一些简单二分题,简单的hash,H(i),字符串题

    说在前面: 题是乱七八糟的. 几个二分的题. (但是我的做法不一定是二分,有些裸暴力. 1. Equations HDU - 1496 输入a,b,c,d问你这个方程有多少解.a*x1^2+b*x2^ ...

  7. POJ 1008 简单模拟题

    e.... 虽然这是一道灰常简单的模拟题.但是米做的时候没有读懂第二个日历的计时方法.然后捏.敲完之后华丽的WA了进一个点.坑点就在一年的最后一天你是该输出本年的.e ...但是我好想并没有..看di ...

  8. [POJ1082&POJ2348&POJ1067&POJ2505&POJ1960]简单博弈题总结

    鉴于时间紧张...虽然知道博弈是个大课题但是花一个上午时间已经极限了... 希望省选过后再回过头来好好总结一遍吧. 接下来为了看着顺眼一点...还是按照难度顺序吧   POJ1082 一道最简单的博弈 ...

  9. HDU 4772 Zhuge Liang&#39;s Password (简单模拟题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4772 题面: Zhuge Liang's Password Time Limit: 2000/1000 ...

随机推荐

  1. Vulnhub实战-JIS-CTF_VulnUpload靶机👻

    Vulnhub实战-JIS-CTF_VulnUpload靶机 下载地址:http://www.vulnhub.com/entry/jis-ctf-vulnupload,228/ 你可以从上面地址获取靶 ...

  2. 编程模仿MySql客服端

    写在前面 通过自己编写的Java代码程序,去模仿实现MySql客服端的简单功能,最终以控制台操作,很像在Dos窗口通过命令操作MySql数据库. 关键问题 在编写过程中遇到的一些小问题和一些值得留心注 ...

  3. 1002 写出这个数 (20 分) java解题

    读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字. 输入格式: 每个测试输入包含 1 个测试用例,即给出自然数 n 的值.这里保证 n 小于 10^100. 输出格式: 在一行内输 ...

  4. 【UE4 C++】定时器 Timer 与事件绑定

    概念 定时执行操作,可执行一次,或循环执行直到手动终止 定时器在全局定时器管理器(FTimerManager 类型)中管理.全局定时器管理器存在于 游戏实例 对象上以及每个 场景 中 定时器需要绑定委 ...

  5. Java序列元素替换

    1.数组 直接赋值. 2.String (1) String是不可变的,只能将新的字符串重新赋给String变量.可使用substring进行拼接: String s="hello" ...

  6. Java:关于 CAS 笔记

    Java:关于 CAS 笔记 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 1. CAS 底层原理 概念 CAS 的全称是 Compare-And-Swap,它 ...

  7. Spring session redis ERR unknown command 'CONFIG'

    部署线上服务启动报错 redis.clients.jedis.exceptions.JedisDataException: ERR unknown command 'CONFIG' Redis CON ...

  8. js--数组的 fill() 填充方法详解

    前言 我们知道了很多了初始化数组的方法,但是初始化数组之后,数组中的每一项元素默认为 empty 空位占位,如何对数组这些空位添加默认的元素,ES6提供了 fill() 方法实现这一操作.本文总结数组 ...

  9. 2021.8.3考试总结[NOIP模拟29]

    T1 最长不下降子序列 数据范围$1e18$很不妙,但模数$d$只有$150$,考虑从这里突破. 计算的式子是个二次函数,结果只与上一个值有关,而模$d$情况下值最多只有$150$个,就证明序列会出现 ...

  10. 21.10.12 test

    题目 **WOJ5110 ** 到 WOJ5113 校内自测没开捆绑,于是输出 -1 和 n! 的程序拿到了高分,我的得分也比期望得分略有提升 T1 problem a \(\color{red}{2 ...