"望月悲叹的最初分块" (妈呀这名字好中二啊(谁叫我要用日本轻小说中的东西命名真是作死))

这里就直接挂csy的题解了,和我的不太一样,但是大概思路还是差不多的,我的做法是和“五彩斑斓的世界”有点类似的维护方法

先考虑如何求区间第k小值。对序列和权值都进行分块,设bi,j表示前j 块中权值在i 块内的数字个数,ci,j 表示前j 块中数字i 的出现次数。那么对于一个询问[l,r] ,首先将零碎部分的贡献加入到临时数组tb 和tc 中,然后枚举答案位于哪一块,确定位于哪一块之后再暴力枚举答案即可在O(√n) 的时间内求出区间第k小值。

接着考虑如何实现区间[l,r]内x 变成y 的功能。显然对于零碎的两块,可以直接暴力重构整块。对于中间的每个整块,如果某一块不含x ,那么无视这一块;否则如果这一块不含y ,那么只需要将x 映射成y ;否则这一块既有x 又有y ,这意味着x 与y 之间发生了合并,不妨直接暴力重构整块。因为有c 数组,我们可以在O(1) 的时间内知道某一块是否有某个数。

考虑什么情况下会发生重构,也就是一个块内发生了一次合并的时候。一开始长度为nn 的序列会提供O(n) 次合并的机会,而每次修改会对零碎的两块各提供一次机会,故总合并次数不超过O(n+m) ,因此当发生合并时直接重构并不会影响复杂度。

那么现在每块中的转换情况只可能是一条条互不相交的链,只需要记录每个初值转换后是什么,以及每个现值对应哪个初值即可。遇到查询的时候,我们需要知道零碎部分每个位置的值,不妨直接重构那两块,然后遍历一遍原数组a即可得到每个位置的值。

在修改的时候,还需要同步维护b 和c 数组,因为只涉及两个权值,因此暴力修改j 这一维也是可以承受的。

总时间复杂度O((n+m)√n) ,空间复杂度O(n√n)

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+,BLO=;
int n,m,a[N],p,vec[N],v2[BLO];
int bl[N],L[BLO],R[BLO];
int s1[BLO][BLO],s2[BLO][N],id[BLO][N],rid[BLO][BLO],pos[N];
int sta[],ttop=,lp=;
char pr[];
template <typename T> inline void read(T &x) {
x=;register char flag,c=getchar();while(c<''||c>'') flag=c,c=getchar();
while(c>=''&&c<='') x=x*+(c^),c=getchar(); if(flag=='-') x=-x;
}
template <typename T> inline void print(T x) {
ttop=; do { sta[++ttop]=(int)(x%),x/=; }while(x);
while(ttop) pr[lp++]=sta[ttop--]+''; pr[lp++]=;
}
inline void reset(int x) { for(register int i=L[x];i<=R[x];++i) a[i]=rid[x][pos[i]]; }
inline void change(int bel,int x,int y) {
int uid=id[bel][x];id[bel][y]=uid,rid[bel][uid]=y,id[bel][x]=;
}
inline void build(int x) {
for(register int i=;i<=p;++i) id[x][rid[x][i]]=;
for(register int i=L[x],idx=;i<=R[x];++i)
if(!id[x][a[i]])
id[x][a[i]]=++idx,rid[x][idx]=a[i];
for(register int i=L[x];i<=R[x];++i) pos[i]=id[x][a[i]];
}
inline void rebuild(int l,int x,int y) {
for(register int i=bl[l];i<=bl[n];++i) {
s2[i][x]+=s2[i-][x],s2[i][y]+=s2[i-][y];
s1[i][bl[x]]+=s1[i-][bl[x]],s1[i][bl[y]]+=s1[i-][bl[y]];
}
}
inline void modify(int l,int r,int x,int y) {
if(s2[bl[r]][x]-s2[bl[l]-][x]==) return ;
for(int i=bl[n];i>=bl[l];--i) {
s2[i][x]-=s2[i-][x],s2[i][y]-=s2[i-][y];
s1[i][bl[x]]-=s1[i-][bl[x]],s1[i][bl[y]]-=s1[i-][bl[y]];
}
if(bl[l]==bl[r]) {
reset(bl[l]);
for(int i=l;i<=r;++i)
if(a[i]==x) {
a[i]=y;
--s2[bl[l]][x],++s2[bl[l]][y];
--s1[bl[l]][bl[x]],++s1[bl[l]][bl[y]];
}
build(bl[l]),rebuild(l,x,y);return ;
}
reset(bl[l]),reset(bl[r]);
for(int i=l;i<=R[bl[l]];++i)
if(a[i]==x) {
a[i]=y;
--s2[bl[l]][x],++s2[bl[l]][y];
--s1[bl[l]][bl[x]],++s1[bl[l]][bl[y]];
}
for(int i=L[bl[r]];i<=r;++i)
if(a[i]==x) {
a[i]=y;
--s2[bl[r]][x],++s2[bl[r]][y];
--s1[bl[r]][bl[x]],++s1[bl[r]][bl[y]];
}
build(bl[l]),build(bl[r]);
for(int i=bl[l]+;i<bl[r];++i) {
if(!s2[i][x]) continue;
if(s2[i][y]) {
reset(i);
for(int j=L[i];j<=R[i];++j)
if(a[j]==x) {
a[j]=y;
--s2[i][x],++s2[i][y];
--s1[i][bl[x]],++s1[i][bl[y]];
}
build(i);
}
else {
s1[i][bl[y]]+=s2[i][x],s1[i][bl[x]]-=s2[i][x];
s2[i][y]+=s2[i][x],s2[i][x]=;
change(i,x,y);
}
}
rebuild(l,x,y);
}
inline int ask(int l,int r,int k) {
int ans=,sum=;
if(bl[l]==bl[r]) {
reset(bl[l]);for(int i=l;i<=r;++i) vec[i]=a[i];
nth_element(vec+l,vec+l+k-,vec+r+),ans=vec[l+k-];
for(int i=l;i<=r;++i) vec[i]=; return ans;
}
reset(bl[l]),reset(bl[r]);
for(int i=l;i<=R[bl[l]];++i) ++vec[a[i]],++v2[bl[a[i]]];
for(int i=L[bl[r]];i<=r;++i) ++vec[a[i]],++v2[bl[a[i]]];
for(int i=;i<=bl[N-];++i) {
if(sum+v2[i]+s1[bl[r]-][i]-s1[bl[l]][i]>=k) {
for(int j=(i-)*p+;j<=i*p;j++) {
if(vec[j]+s2[bl[r]-][j]-s2[bl[l]][j]+sum>=k) { ans=j;goto FLAG; }
else sum+=vec[j]+s2[bl[r]-][j]-s2[bl[l]][j];
}
}
else sum+=v2[i]+s1[bl[r]-][i]-s1[bl[l]][i];
}
FLAG:
for(int i=l;i<=R[bl[l]];++i) --vec[a[i]],--v2[bl[a[i]]];
for(int i=L[bl[r]];i<=r;++i) --vec[a[i]],--v2[bl[a[i]]];
return ans;
}
int main() {
read(n),read(m),p=sqrt(N)+;
for(int i=;i<N;++i) bl[i]=(i-)/p+;
for(int i=;i<=n;++i) read(a[i]);
for(int i=;i<=bl[n];++i)
L[i]=(i-)*p+,R[i]=i*p;R[bl[n]]=n;
for(int x=;x<=bl[n];++x) build(x);
for(int x=;x<=bl[n];++x) {
for(int i=;i<N;++i) s2[x][i]=s2[x-][i];
for(int i=;i<=bl[N-];++i) s1[x][i]=s1[x-][i];
for(int i=L[x];i<=R[x];++i) ++s1[x][bl[a[i]]],++s2[x][a[i]];
}
for(;m;--m) {
int opt,x,y;read(opt),read(x),read(y);
if(opt==) {int z,w;read(z),read(w),modify(x,y,z,w);}
else {int k;read(k),print(ask(x,y,k));}
}
pr[--lp]='\0'; puts(pr);
return ;
}

[Ynoi2018]未来日记的更多相关文章

  1. [Ynoi2018]未来日记(分块)

    分块神题. 看了一会儿题解,看懂了思路,然后写了两个小时,调了一个多小时,好多地方写错了. 我们考虑对序列和值域都分块.\(sum1[i][j]\) 表示前 \(i\) 个块,第 \(j\) 块值域有 ...

  2. 「Ynoi2018」未来日记

    「Ynoi2018」未来日记 区间x->y,kth值... 不管了,先序列分块... 查询 第k值,假定知道每个数的权值,对值域分块. 对于整块,维护前\(i\)个块当中,值域在\(j\)块里以 ...

  3. ynoi2018

    题解: 全分块是啥操作啊.. 而且都好难.. 1.未来日记 这个比较简单 对每个块开个线段树维护权值 $n\sqrt{n}logn$ 这个会炸空间 并不能做... 但还是说一下做法 首先考虑分块 然后 ...

  4. [Ynoi2018]五彩斑斓的世界

    题目描述 二阶堂真红给了你一个长为n的序列a,有m次操作 1.把区间[l,r]中大于x的数减去x 2.查询区间[l,r]中x的出现次数 题解 做YNOI真**爽... 我们发现这道题的操作非常诡异,把 ...

  5. [Ynoi2018]末日时在做什么?有没有空?可以来拯救吗?

    这道题真的超级...毒瘤 + 卡常 + 耗 RP 啊... 传送门 noteskey 题解看 shadowice 大仙 的 code 如果发现自己 T 掉了,别心急,洗把脸再交一遍试试... //by ...

  6. 洛谷P4117 [Ynoi2018]五彩斑斓的世界 [分块,并查集]

    洛谷 Codeforces 又是一道卡常题-- 思路 YNOI当然要分块啦. 分块之后怎么办? 零散块暴力,整块怎么办? 显然不能暴力改/查询所有的.考虑把相同值的用并查集连在一起,这样修改时就只需要 ...

  7. 【bzoj4810】【ynoi2018】由乃的玉米田

    4810: [Ynoi2017]由乃的玉米田 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 1090  Solved: 524[Submit][Sta ...

  8. 【洛谷5398】[Ynoi2018]GOSICK(二次离线莫队)

    题目: 洛谷 5398 当我刚学莫队的时候,他们告诉我莫队能解决几乎所有区间问题: 现在,当我发现一个区间问题似乎难以用我所了解的莫队解决的时候,他们就把这题的正解叫做 XXX 莫队.--题记 (以上 ...

  9. 洛谷P5398 [Ynoi2018]GOSICK(二次离线莫队)

    题面 传送门 题解 维包一生推 首先请确保您会二次离线莫队 那么我们现在的问题就是怎么转移了,对于\(i\)和前缀\([1,r]\)的贡献,我们拆成\(b_i\)和\(c_i\)两部分,其中\(b_i ...

随机推荐

  1. 设置tomcat支持软连接

    一般开发时不会在tomcat安装目录/data/tomcat/webapps/ROOT 下去,上传部署:而是建立软连接,在tomcat安装目录之外操作,比如执行git pull拉取项目,而tomcat ...

  2. php实现遍历目录

    用递归方法实现目录的遍历: <?php header("Content-type: text/html; charset=utf-8"); date_default_time ...

  3. C#保留小数点后几位

    String.Format("{0:N1}", a) 保留小数点后一位 String.Format("{0:N2}", a) 保留小数点后两位 String.F ...

  4. mybatis分页查询的万能模板

    分页查询项目里太多了,而这种分页查询,在mybatis里面的配置几乎一模一样,今天就整理一个比较好和实用的模板,供以后直接Ctrl+C <select id="queryMember& ...

  5. GUI开发:实时显示摄像头图像

    import tkinter as tk from PIL import Image, ImageTk import cv2 import numpy as np import time g_exit ...

  6. 开始PYTHON之路

    曾经的功献给了球场酒精 曾经的激情也献给了爱情 曾经的智商用来副本求生 曾经的VB6老迈的只剩点0 曾经的SQL2000都不兼容 曾经........ 还有一些理想没有实现 还得继续在这个世界谋生 岁 ...

  7. 关于jQuery实现CheckBox全选只能生效一次的问题

    //这代码只有一次全选.全不选的效果 第三次点击checkall会没有任何效果 $("#checkall").click(function(){ $('input[name=&qu ...

  8. Arm11-mini6410入坑

    Mini6410 学习Stm32的时候原子哥的资料真全啊,而且原子哥在他论坛也解答问题.然而现在学习ARM买了一套友善之臂的开发板,官方的资料只能刚好入门而已,其实入门都算不上.看了一下,网上的资料很 ...

  9. CSS组合设计输入框和按钮生成自定义关键字查询栏

    效果图: html代码: <!DOCTYPE html> <head> <title></title> </head> <body&g ...

  10. Request对象和Response对象 JsonResponse对象 和 Django shortcut functions 和QueryDict对象

    request request属性 属性: django将请求报文中的请求行.头部信息.内容主体封装成 HttpRequest 类中的属性. 除了特殊说明的之外,其他均为只读的. ''' 0.Http ...