辣么这个题可是真难
首先利用Hash表判断是否可以用
T2则是利用并查集的siz
好难啊
枚举区间段可以用BIT
我实际就没懂
#include<bits/stdc++.h>
using namespace std;
typedef int INT;
#define int long long
inline void read(int &x){
x=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
const int N=1e6+1000;
struct BIT{
int T[N];
inline int lowbit(int x){return x&(-x);}
inline void update(int x,int val){while(x<N){T[x]+=val;x+=lowbit(x);}}
inline int query(int x){if(x==-1) return 0;int ret=0;while(x){ret+=T[x];x-=lowbit(x);}return ret;}
}T;
struct Heap{
priority_queue<int>In,Del;
void Insert(int x){In.push(x);}
void Delete(int x){Del.push(x);}
int Top(){while(Del.size()&&In.top()==Del.top()){In.pop();Del.pop();};return (In.size()?In.top():0);}
}q;
int pre[N]={};
int v[N]={};
int fa[N]={};
int n,m;
vector<int> A[N];
int pos[N]={};
int siz[N]={};
int find(int x){
if(fa[x]==x)return x;
else return fa[x]=find(fa[x]);
}
INT main(){
read(n);
read(m);
for(int i=1;i<=n;i++){
read(v[i]);
fa[i]=i;
A[v[i]].push_back(i);
pos[i]=A[v[i]].size()-1;
siz[i]=1;
}
fa[0]=1;
fa[n+1]=n+1;
siz[n+1]=1;
int Up_Low=n;
int sum=0;
// cout<<find(1);
/*for(int i=1;i<n;i++){
if(pos[i]) q.Delete(A[v[i]][pos[i]-1]);
if(pos[i]==(int)A[v[i]].size()-1)
{
for(int j=find(A[v[i]][0]);j<i;j=fa[j]) T.update(j,1),siz[find(j+1)]+=siz[j],fa[j]=fa[j+1];
}
else q.Insert(i);
int k=q.Top();
sum+=i-k-(T.query(i-1)-T.query(k-1));
cout<<sum<<'\n';
// j=find(max(k,i-n/2));
// if(j<i) ans=min(ans,abs(n-2*(i-j)));
// j-=siz[j];
// if(j>=k) ans=min(ans,abs(n-2*(i-j)));
}*/
for(int i=1;i<n;i++){
// cout<<i<<'\n';
if(pos[i])q.Delete(A[v[i]][pos[i]-1]);
// cout<<"234789478"<<'\n';
// cout<<A[v[i]].size()<<'\n';
//
if(pos[i]==(int)A[v[i]].size()-1){
// cout<<"in"<<'\n';
for(int j=find(A[v[i]][0]);j<i;j=fa[j]){
// cout<<j<<" k"<<'\n';
T.update(j,1);
siz[find(j+1)]+=siz[j];
fa[j]=fa[j+1];
// cout<<"j= "<<j<<'\n';
}
}
else q.Insert(i);
int now=q.Top();
// cout<<"13"<<'\n';
sum+=i-now-(T.query(i-1)-T.query(now-1));
// cout<<sum<<'\n';
int idx=find(max(now,i-n/2));
if(idx<i) Up_Low=min(Up_Low,abs(n-2*(i-idx)));
idx-=siz[idx];
if(idx>=now) Up_Low=min(Up_Low,abs(n-2*(i-idx)));
}
cout<<sum<<" "<<Up_Low;
}