称区间$[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. windows中抓包命令,以及保存为多个文件的方法

    本文主要介绍windows中抓包命令,以及保存为多个文件的方法 说一说保存为多个文件存储数据包这个问题的由来,一般如果长时间抓包,有可能需要等上几个小时,因为这个时候抓包的内容都是存放在内存中的,几个 ...

  2. 重磅 | 阿里开源首个 Serverless 开发者平台 Serverless Devs

    Serverless 从概念提出到应用,已经走过了 8 个年头,开发者对 Serverless 的使用热情不断高涨.为帮助开发者实现一键体验多云产品,极速部署 Serverless 项目,10 月 2 ...

  3. django3上线部署踩的坑

    好久没有用过django写项目了,最近公司开发个官网,一时兴起就拿来练练手,这不用不知道,一用吓一跳啊. 才多久,版本都到3.0了. 踩坑一:运行项目时失败报错,后来查找资料发现, 当你使用djang ...

  4. Elasticsearch 中为什么选择倒排索引而不选择 B 树索引

    目录 前言 为什么全文索引不使用 B+ 树进行存储 全文检索 正排索引 倒排索引 倒排索引如何存储数据 FOR 压缩 RBM 压缩 倒排索引如何存储 字典树(Tria Tree) FST FSM 构建 ...

  5. gridlayout在kv中的引用

    from kivy.app import App from kivy.uix.gridlayout import GridLayout class GridLayoutWidget(GridLayou ...

  6. RogrePirates Scrum Meeting 博客汇总

    RogrePirates 博客目录 一.Scrum Meeting 1.Alpha阶段 第一次会议 第二次会议 第三次会议 第四次会议 第五次会议 第六次会议 第七次会议 第八次会议 第九次会议 第十 ...

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

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

  8. 攻防世界 杂项 4.something_in_image

    这是原题 我这里使用编辑器打开,一看乱码也挺多的,于是想了想ctrl+f搜索一下flag关键字吧,结果答案出来了(flag不少,多搜索几次) Flag{yc4pl0fvjs2k1t7T}

  9. 简单易懂讲IO

    流式 IO 是传统 IO,通过构造输入输出流,讲信息从一个地方读取,输出到另一个地方.常见的有读取文件以及写入文件. 基本 API 流失 IO 基本可以分为两个门派,一个以 InputStream 和 ...

  10. Python ImportError: No module named '_tkinter', please install the python3-tk package

    ImportError: No module named '_tkinter', please install the python3-tk package 这个问题的原因是使用的python3环境内 ...