前言

第一篇模拟赛题思路总结

题目相关

题目链接

题目大意

给定一个长度为nnn序列,每一个位置iii都有一种颜色aia_iai​
现在有mmm次操作,操作分两种:
第一种操作,将所有颜色xxx都替换成yyy
第二种操作,询问所有满足两个点的颜色分别为xxx和yyy的点对的最小距离值
强制在线

数据范围

n,m,ai,x,y≤200000n,m,a_i,x,y\le200000n,m,ai​,x,y≤200000

题解

暴力分块…
按照出现次数进行分块
我们来列举一下要维护的信息:
颜色数组
对于所有颜色都维护出现位置的有序数组(我们发现输入后处理这个信息复杂度是Θ(n)\Theta(n)Θ(n)的,可以使用vector)
对于出现次数≥n\ge\sqrt n≥n​的颜色,额外维护其到其它所有颜色的答案(输入后直接把整个序列扫一遍即可,我们发现满足条件的颜色只有Θ(n)\Theta(\sqrt n)Θ(n​)种,总复杂度Θ(nn)\Theta(n\sqrt n)Θ(nn​),空间复杂度同)。为了方便表示,设ans[i][j]代表当前iii颜色是L颜色,其与jjj颜色的答案
为了方便描述,我们称出现次数≥n\ge\sqrt n≥n​的颜色为L颜色,称出现次数≤n\le\sqrt n≤n​的颜色为S颜色

第一种操作
  • L颜色&L颜色
    归并维护有序数组,我们发现这种情况最多进行n\sqrt nn​次,所以这部分的复杂度为Θ(nn)\Theta(n\sqrt n)Θ(nn​)
    Θ(n)\Theta(n)Θ(n)维护颜色数组,总复杂度Θ(nn)\Theta(n\sqrt n)Θ(nn​)
    到其它所有颜色的答案也Θ(n)\Theta(n)Θ(n)维护,总复杂度Θ(nn)\Theta(n\sqrt n)Θ(nn​)
  • S颜色&S颜色(注意,合并完后如果出现次数大于n\sqrt nn​,需要将S颜色转化成L颜色,容易发现这里最多出现n\sqrt nn​次,所以总复杂度Θ(nn)\Theta(n\sqrt n)Θ(nn​))
    归并维护有序数组,复杂度Θ(n)\Theta(\sqrt n)Θ(n​),总复杂度为Θ(mn)\Theta(m\sqrt n)Θ(mn​)
    Θ(n)\Theta(\sqrt n)Θ(n​)暴力维护颜色数组,总复杂度Θ(mn)\Theta(m\sqrt n)Θ(mn​)
  • S颜色&L颜色
    S颜色并入L颜色与L颜色并入S颜色的本质是一样的,唯一不同的在于L颜色并入S颜色后颜色数组中需要更新的数据不同
    我们发现,L颜色xxx并入S颜色yyy,可以反向并入(即yyy并入xxx),并重新记下编号
    我们发现答案数组并不好维护,所以我们可以开一个缓冲区,记录后面加入的零散的该颜色的位置(若缓冲区大小大于等于n\sqrt nn​就直接用缓冲区更新,复杂度是Θ(nn)\Theta(n\sqrt n)Θ(nn​)的)
    更新缓冲区数组的复杂度是Θ(mn)\Theta(m\sqrt n)Θ(mn​)的

注意:任意颜色合并完毕后需要更新n\sqrt nn​个L颜色中对应的值

第二种操作
  • L颜色&L颜色
    我们发现,答案数组维护的是L颜色的非缓冲区内位置与别的颜色之间的答案,那么我们也就只需要将min(ans[x][y],ans[y][x])的值min上缓冲区之间的答案,复杂度Θ(n)\Theta(\sqrt n)Θ(n​)
  • L颜色&S颜色
    将ans[x][y]min上缓冲区的答案,复杂度Θ(n)\Theta(\sqrt n)Θ(n​)
  • S颜色&S颜色
    一次归并即可

代码

贴上AC代码

#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
namespace fast_IO
{const int IN_LEN=10000000,OUT_LEN=10000000;char ibuf[IN_LEN],obuf[OUT_LEN],*ih=ibuf+IN_LEN,*oh=obuf,*lastin=ibuf+IN_LEN,*lastout=obuf+OUT_LEN-1;inline char getchar_(){return (ih==lastin)&&(lastin=(ih=ibuf)+fread(ibuf,1,IN_LEN,stdin),ih==lastin)?EOF:*ih++;}inline void putchar_(const char x){if(oh==lastout)fwrite(obuf,1,oh-obuf,stdout),oh=obuf;*oh++=x;}inline void flush(){fwrite(obuf,1,oh-obuf,stdout);}
}
using namespace fast_IO;
#define getchar() getchar_()
#define putchar(x) putchar_((x))
#define rg register
typedef long long LL;
template <typename T> inline T max(const T a,const T b){return a>b?a:b;}
template <typename T> inline T min(const T a,const T b){return a<b?a:b;}
template <typename T> inline void mind(T&a,const T b){a=a<b?a:b;}
template <typename T> inline void maxd(T&a,const T b){a=a>b?a:b;}
template <typename T> inline T abs(const T a){return a>0?a:-a;}
template <typename T> inline void swap(T&a,T&b){T c=a;a=b;b=c;}
template <typename T> inline T gcd(const T a,const T b){if(!b)return a;return gcd(b,a%b);}
template <typename T> inline T lcm(const T a,const T b){return a/gcd(a,b)*b;}
template <typename T> inline T square(const T x){return x*x;};
template <typename T> inline void read(T&x)
{char cu=getchar();x=0;bool fla=0;while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}while(isdigit(cu))x=x*10+cu-'0',cu=getchar();if(fla)x=-x;
}
template <typename T> inline void printe(const T x)
{if(x>=10)printe(x/10);putchar(x%10+'0');
}
template <typename T> inline void print(const T x)
{if(x<0)putchar('-'),printe(-x);else printe(x);
}
const int INF=998244353;
unsigned int PART;
int n,m,col[200001];
int lsh[200001],tot,lastans;
std::vector<int>p[200001],h[200001],ans[200001];
std::vector<int>::iterator Posu,Posv;
void add(std::vector<int>&w,std::vector<int>&v)
{std::vector<int>u;u.clear();for(unsigned int i=0;i<w.size();i++)u.push_back(w[i]);w.clear();Posu=u.begin(),Posv=v.begin();while(Posu!=u.end()&&Posv!=v.end())if((*Posu)<(*Posv))w.push_back(*Posu),Posu++;else w.push_back(*Posv),Posv++;while(Posu!=u.end())w.push_back(*Posu),Posu++;while(Posv!=v.end())w.push_back(*Posv),Posv++;v.clear();
}
int calc(std::vector<int>&u,std::vector<int>&v)
{int ans=INF,lasu=-INF,lasv=-INF;Posu=u.begin(),Posv=v.begin();while(Posu!=u.end()&&Posv!=v.end())if((*Posu)<(*Posv))lasu=*Posu,Posu++,mind(ans,lasu-lasv);else lasv=*Posv,Posv++,mind(ans,lasv-lasu);while(Posu!=u.end())lasu=*Posu,Posu++,mind(ans,lasu-lasv);while(Posv!=v.end())lasv=*Posv,Posv++,mind(ans,lasv-lasu);return ans;
}
int bak[200001];
bool isL[200001];
void L_color_update(const int u)
{std::vector<int>*U=&ans[u];for(rg int i=1;i<=tot;i++)(*U)[i]=INF;int close=INF;for(rg int i=1;i<=n;i++,close++)if(col[i]==u)close=0;else mind((*U)[col[i]],close);close=INF;for(rg int i=n;i>=1;i--,close++)if(col[i]==u)close=0;else mind((*U)[col[i]],close);
}
bool is[200001];
void upd(std::vector<int>&u)
{for(Posu=u.begin();Posu!=u.end();Posu++)is[*Posu]=1;u.clear();
}
int Lstack[200001],Ltop;
void push(const int x){Lstack[++Ltop]=x,ans[x].resize(200001),isL[x]=1;}
void pop(const int x)
{ans[x].clear(),isL[x]=0;for(rg int i=1;i<=Ltop;i++)if(Lstack[i]==x){Ltop--;for(rg int j=i;j<=Ltop;j++)Lstack[j]=Lstack[j+1];return;}
}
int main()
{read(n),read(m),PART=sqrt(n);for(rg int i=1;i<=n;i++){read(col[i]);if(!lsh[col[i]])lsh[col[i]]=++tot;col[i]=lsh[col[i]];p[col[i]].push_back(i);}for(rg int i=1;i<=tot;i++)if(p[i].size()>=PART){push(i);L_color_update(i);}for(rg int i=1;i<=m;i++){int opt,x,y;read(opt),read(x),read(y);x^=lastans,y^=lastans;if(opt==1){const int X=lsh[x],Y=lsh[y];if(!X||x==y)continue;if(!Y){lsh[x]=0;lsh[y]=X;continue;}if(isL[X]){if(isL[Y]){upd(p[X]),upd(p[Y]),upd(h[X]),upd(h[Y]);for(rg int j=1;j<=n;j++)if(is[j])p[Y].push_back(j),is[j]=0,col[j]=Y;L_color_update(Y);lsh[x]=0,pop(X);for(rg int j=1;j<=Ltop;j++){const int v=Lstack[j];ans[v][Y]=ans[Y][v];}}else{for(Posv=p[Y].begin();Posv!=p[Y].end();Posv++)col[*Posv]=X;add(h[X],p[Y]);for(rg int j=1;j<=Ltop;j++){const int v=Lstack[j];mind(ans[v][X],ans[v][Y]),ans[v][Y]=INF;}if(h[X].size()>=PART){upd(p[X]),upd(h[X]);for(rg int j=1;j<=n;j++)if(is[j])p[X].push_back(j),is[j]=0;L_color_update(X);}lsh[x]=0,lsh[y]=X;}}else{if(isL[Y]){for(Posv=p[X].begin();Posv!=p[X].end();Posv++)col[*Posv]=Y;add(h[Y],p[X]);for(rg int j=1;j<=Ltop;j++){const int v=Lstack[j];mind(ans[v][Y],ans[v][X]),ans[v][X]=INF;}if(h[Y].size()>=PART){upd(p[Y]),upd(h[Y]);for(rg int j=1;j<=n;j++)if(is[j])p[Y].push_back(j),is[j]=0;L_color_update(Y);}lsh[x]=0;}else{for(Posv=p[X].begin();Posv!=p[X].end();Posv++)col[*Posv]=Y;add(p[Y],p[X]);for(rg int j=1;j<=Ltop;j++){const int v=Lstack[j];mind(ans[v][Y],ans[v][X]),ans[v][X]=INF;}if(p[Y].size()>=PART){push(Y);upd(p[Y]);for(rg int j=1;j<=n;j++)if(is[j])p[Y].push_back(j),is[j]=0;L_color_update(Y);for(rg int j=1;j<=Ltop;j++){const int v=Lstack[j];ans[v][Y]=ans[Y][v];}}lsh[x]=0;}}}else{if(!lsh[x]||!lsh[y])putchar('y'),putchar('y'),putchar('b'),putchar(' '),putchar('i'),putchar('s'),putchar(' '),putchar('o'),putchar('u'),putchar('r'),putchar(' '),putchar('r'),putchar('e'),putchar('d'),putchar(' '),putchar('s'),putchar('u'),putchar('n'),putchar(' '),putchar('a'),putchar('n'),putchar('d'),putchar(' '),putchar('z'),putchar('s'),putchar('y'),putchar(' '),putchar('i'),putchar('s'),putchar(' '),putchar('o'),putchar('u'),putchar('r'),putchar(' '),putchar('b'),putchar('l'),putchar('u'),putchar('e'),putchar(' '),putchar('m'),putchar('o'),putchar('o'),putchar('n'),lastans=0;else{const int X=lsh[x],Y=lsh[y];if(isL[X]){if(isL[Y])print(lastans=min(min(ans[X][Y],ans[Y][X]),calc(h[X],h[Y])));else print(lastans=min(ans[X][Y],calc(h[X],p[Y])));}else{if(isL[Y])print(lastans=min(ans[Y][X],calc(p[X],h[Y])));else print(lastans=calc(p[X],p[Y]));}}putchar('\n');}}return flush(),0;
}

总结

分块好题,很妙的思路

模拟赛-20190114-新魔法(distance)相关推荐

  1. 2021年暑假数学建模第一次模拟赛:新冠疫情预测(插值,时间序列,微分方程建模)

    本系列赛题.数据获取: 2021年暑假数学建模模拟赛(赛题+数据+分析) 不直接提供论文等资料,分析已经很详细了 整理不易,欢迎点赞+关注+收藏 2021年暑假数学建模第一次模拟赛:新冠疫情预测(插值 ...

  2. 省选模拟赛记录(越往下越新哦~~~)

    LOG 模拟赛 第一次见尼玛这么给数据范围的-- 开考有点困,迷迷糊糊看完了三道题,真的是像老吕说的那样,一道都不会-- 思考T1,感觉有点感觉,但是太困了,就先码了暴力,发现打表可以50分,于是就大 ...

  3. ssl提高组周六模拟赛【2018.9.8】

    前言 开学后,新学年新气象,学校题库也迎来了新的改动,界面大改变,也可以比赛了. 所以这周就有比赛了,而在纪中被虐习惯后回来渴望继续被虐就来参加提高组模拟赛(反正今年也参加提高组) 成绩 只放Rank ...

  4. 2022.07.16模拟赛总结

    7.16模拟赛总结 总述 题目详情 T1 取餐号 T2 堆人塔 T3 钦定IOI选手 20pts做法 100pts做法 T4 攻打恶魔之巅 水水版DP T5 抉择 暑假集训模拟赛Day1 总述 真想不 ...

  5. [GRYZ]寒假模拟赛

    写在前面 这是首次广饶一中的OIERS自编自导,自出自做(zuo)的模拟赛. 鉴于水平气压比较低,机(wei)智(suo)的WMY/XYD/HYXZC就上网FQ下海找了不少水(fei)题,经过他们优( ...

  6. NOI.AC NOIP模拟赛 第六场 游记

    NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...

  7. 2020年蓝桥杯模拟赛2020.3.25直播笔记

    2020年蓝桥杯模拟赛解题报告(CPP版本) 第八题 长草的bfs写法[我想暴力模拟O kmn] 深搜会爆 bfs像投到水里的涟漪 问题: const int dx[] = {1, 0, -1, 0} ...

  8. 2021年 第12届 蓝桥杯 第3次模拟赛真题详解及小结【Java版】

    蓝桥杯 Java B组 省赛决赛 真题详解及小结汇总[2013年(第4届)~2021年(第12届)] 第11届 蓝桥杯-第1.2次模拟(软件类)真题-(2020年3月.4月)-官方讲解视频 说明:大部 ...

  9. 10.30 NFLS-NOIP模拟赛 解题报告

    总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没 ...

最新文章

  1. 免费报名 | 微软全双工语音对话以及在智能硬件上的应用
  2. 训练模型前数据是不是这样处理会更好
  3. android 按钮 叠加,android - 叠加层按钮在Android 4.3中不起作用 - 堆栈内存溢出
  4. HttpClient模拟http请求
  5. 并查集/poj1182 noi2001食物链eat
  6. 有关可变形部件模型(Deformable Part Model)的一些说明
  7. java班长竞选投票_竞选班长采取投票式,引家长不满,班主任:您说该怎么选?...
  8. 面试题17.04.消失的数字
  9. 翻译附图中的大量文字
  10. 【Spring】Spring 父子容器
  11. 《Android游戏开发详解》一1.8 控制流程第2部分——while和for循环
  12. 技校毕业计算机应用技术,技校计算机应用毕业生自我鉴定
  13. 随时发生的网络攻击怎么防?这是一场网络安全的全民保卫战!
  14. pycharm中同时注释多行代码
  15. 客房管理系统类毕业论文文献都有哪些?
  16. 超分算法之SRCNN
  17. 关于awk 中如何使用 if条件判断句
  18. python画动态表情包_20行代码制作字符画版小黄鸭表情包
  19. php源雄武,8个新鲜的PHP常用代码
  20. html日程管理,日程管理.html

热门文章

  1. 简单介绍日志的发展历史
  2. MapReduce的构思和框架结构
  3. 后台服务系统之什么是dubbo
  4. DateFormat类的format方法和parse方法
  5. 使用网络存储SAN和NAS
  6. 基于multisim的fm调制解调_高通二代5G调制解调器骁龙X55实现7Gbps高速率,透露5G三大关键点...
  7. DEDECMS中Showmsg的用法及参数介绍
  8. 洛谷 P1983 车站分级
  9. 国家文物局:长城沿线群众是文物保护的重要力量
  10. Unity3D如何有效地组织代码?(转)