[loj3408]lancllords
考虑归并排序,问题即如何合并两个序列
-
不妨假设,将按下标奇偶性划分为和
-
将与归并,得到序列
-
对于中的元素,仅需与(中)中相邻两数间的中元素比较
比较次数为,用莫队实现,操作次数为(其中为区间长度)
综上,复杂度即,由主定理得
在此基础上,原问题复杂度即,由主定理得
综上,总比较次数为,总移动次数为
#include<bits/stdc++.h>
#include "lancllords.h"
using namespace std;
typedef vector<int>vi;
const int N=150005;
int p,q,K;vi ans;
unordered_map<int,bool>mat[N];
struct Node{
int x,y;
bool operator < (const Node &n)const{
return (x/K!=n.x/K ? x/K<n.x/K : y<n.y);
}
};vector<Node>Q;
bool cmp(int x,int y){
if (mat[x].find(y)!=mat[x].end())return mat[x][y];
while (p<x)p++,inc_p();
while (p>x)p--,dec_p();
while (q<y)q++,inc_q();
while (q>y)q--,dec_q();
return mat[x][y]=cmp();
}
vi merge(int l,vi vx,vi vy){
int sx=vx.size(),sy=vy.size();
if (sx<sy)swap(vx,vy),swap(sx,sy);
if (!sy)return vx;
int k=0;vi v;
for(int i=1;i<sx;i+=2)v.push_back(vx[i]);
vy=merge(l,v,vy),sy=vy.size();
Q.clear();
for(int i=0;i<sx;i+=2){
while ((k<sy)&&((i==sx-1)||(vy[k]!=vx[i+1])))Q.push_back(Node{vx[i],vy[k++]});
if (k<sy)k++;
}
if (!Q.empty()){
K=max((int)(l/sqrt(Q.size())),1);
sort(Q.begin(),Q.end());
for(Node i:Q)cmp(i.x,i.y);
}
k=0,v.clear();
for(int i=0;i<sx;i+=2){
bool flag=0;
while ((k<sy)&&((i==sx-1)||(vy[k]!=vx[i+1]))){
if ((!flag)&&(cmp(vx[i],vy[k])))flag=1,v.push_back(vx[i]);
v.push_back(vy[k++]);
}
if (!flag)v.push_back(vx[i]);
if (k<sy)v.push_back(vy[k++]);
}
while (k<sy)v.push_back(vy[k++]);
return v;
}
vi solve(int l,int r){
if (l==r)return vi{l};
int mid=(l+r>>1);
return merge(r-l+1,solve(l,mid),solve(mid+1,r));
}
vi answer(int n){
vi v=solve(0,n-1);
ans.resize(n);
for(int i=0;i<n;i++)ans[v[i]]=i;
return ans;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2021-04-09 [cf1349E]Slime and Hats