模拟赛-20190114-新魔法(distance)
前言
第一篇模拟赛题思路总结
题目相关
题目链接
题目大意
给定一个长度为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)相关推荐
- 2021年暑假数学建模第一次模拟赛:新冠疫情预测(插值,时间序列,微分方程建模)
本系列赛题.数据获取: 2021年暑假数学建模模拟赛(赛题+数据+分析) 不直接提供论文等资料,分析已经很详细了 整理不易,欢迎点赞+关注+收藏 2021年暑假数学建模第一次模拟赛:新冠疫情预测(插值 ...
- 省选模拟赛记录(越往下越新哦~~~)
LOG 模拟赛 第一次见尼玛这么给数据范围的-- 开考有点困,迷迷糊糊看完了三道题,真的是像老吕说的那样,一道都不会-- 思考T1,感觉有点感觉,但是太困了,就先码了暴力,发现打表可以50分,于是就大 ...
- ssl提高组周六模拟赛【2018.9.8】
前言 开学后,新学年新气象,学校题库也迎来了新的改动,界面大改变,也可以比赛了. 所以这周就有比赛了,而在纪中被虐习惯后回来渴望继续被虐就来参加提高组模拟赛(反正今年也参加提高组) 成绩 只放Rank ...
- 2022.07.16模拟赛总结
7.16模拟赛总结 总述 题目详情 T1 取餐号 T2 堆人塔 T3 钦定IOI选手 20pts做法 100pts做法 T4 攻打恶魔之巅 水水版DP T5 抉择 暑假集训模拟赛Day1 总述 真想不 ...
- [GRYZ]寒假模拟赛
写在前面 这是首次广饶一中的OIERS自编自导,自出自做(zuo)的模拟赛. 鉴于水平气压比较低,机(wei)智(suo)的WMY/XYD/HYXZC就上网FQ下海找了不少水(fei)题,经过他们优( ...
- NOI.AC NOIP模拟赛 第六场 游记
NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...
- 2020年蓝桥杯模拟赛2020.3.25直播笔记
2020年蓝桥杯模拟赛解题报告(CPP版本) 第八题 长草的bfs写法[我想暴力模拟O kmn] 深搜会爆 bfs像投到水里的涟漪 问题: const int dx[] = {1, 0, -1, 0} ...
- 2021年 第12届 蓝桥杯 第3次模拟赛真题详解及小结【Java版】
蓝桥杯 Java B组 省赛决赛 真题详解及小结汇总[2013年(第4届)~2021年(第12届)] 第11届 蓝桥杯-第1.2次模拟(软件类)真题-(2020年3月.4月)-官方讲解视频 说明:大部 ...
- 10.30 NFLS-NOIP模拟赛 解题报告
总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没 ...
最新文章
- 免费报名 | 微软全双工语音对话以及在智能硬件上的应用
- 训练模型前数据是不是这样处理会更好
- android 按钮 叠加,android - 叠加层按钮在Android 4.3中不起作用 - 堆栈内存溢出
- HttpClient模拟http请求
- 并查集/poj1182 noi2001食物链eat
- 有关可变形部件模型(Deformable Part Model)的一些说明
- java班长竞选投票_竞选班长采取投票式,引家长不满,班主任:您说该怎么选?...
- 面试题17.04.消失的数字
- 翻译附图中的大量文字
- 【Spring】Spring 父子容器
- 《Android游戏开发详解》一1.8 控制流程第2部分——while和for循环
- 技校毕业计算机应用技术,技校计算机应用毕业生自我鉴定
- 随时发生的网络攻击怎么防?这是一场网络安全的全民保卫战!
- pycharm中同时注释多行代码
- 客房管理系统类毕业论文文献都有哪些?
- 超分算法之SRCNN
- 关于awk 中如何使用 if条件判断句
- python画动态表情包_20行代码制作字符画版小黄鸭表情包
- php源雄武,8个新鲜的PHP常用代码
- html日程管理,日程管理.html