Into Blocks(不帶修改的版本)
題意:給定一個序列,通過改變其中的數字使所有相同的數字在數組中都是相鄰的,改變數字的方式爲:將數組中某個數字全部修改爲另外一個數字。求最少需要改變的元素
思路:
- 由於最終狀態肯定是“一塊一塊”的,每一塊中都是一樣的數字
- 因此考慮預處理每種數字最靠右的位置,然後從左到右掃描整個序列
- 掃描的過程中以出現的數字的最靠右的位置爲界限,並且每遇到一個新數字就更新界限
- 而當掃描到界限位置出,表明改變當前區域內的數字不會影響到後面的區域,因此找出當前區域內出現次數最多的數字,並且把其他數字都改爲當前數字即爲最優
- 妙啊!heyuhhh nb!
題面描述
#include "bits/stdc++.h"
#define hhh printf("hhh\n")
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
using namespace std;
typedef long long ll;
typedef pair<int,int> pr;
inline int read() {int x=0;char c=getchar();while(c<'0'||c>'9')c=getchar();while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return x;}
const int maxn = 2e5+10;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const double eps = 1e-7;
int n, q, ans;
int a[maxn], x[maxn], cnt[maxn];
inline void max(int &a, int b) { if(a<b) a=b; }
int main() {
//ios::sync_with_stdio(false); cin.tie(0);
n=read(), q=read();
for(int i=1; i<=n; ++i) cnt[x[a[i]=read()]=i,a[i]]++;
for(int i=1; i<=n; ++i) {
int l=i, r=x[a[i]], m=cnt[a[i]];
while(i<r) ++i, max(r,x[a[i]]), max(m,cnt[a[i]]);
ans+=r-l+1-m;
}
cout<<ans<<endl;
}
壓行過猛,竟然壓到第一了
#include"bits/stdc++.h"
const int N=2e5+1;
int i,n,q,p,l,r,m,a[N],x[N],c[N];
int main(){
scanf("%d%d",&n,&q);
for(i=1;i<=n;++i)scanf("%d",&a[i]),c[x[a[i]]=i,a[i]]++;
for(i=1;i<=n;++i){
l=i,r=x[a[i]],m=c[a[i]];
while(i<r)++i,r=std::max(r,x[a[i]]),m=std::max(m,c[a[i]]);
p+=r-l+1-m;
}
printf("%d",p);
}