rt,思路是先把串内能消的消了。
然后合并后首尾合起来消。
然后最后中间剩下的串如果多于一个数就删不了了。
只剩一个数的话就特判如果能删完那么还可以再删一次首尾。
我看题解好像也是这种做法,但是写法有些不同,怀疑是写法上挂了。
调了很久无果,遂发帖求助。
谢谢。
#include <bits/stdc++.h>
#define lint __int128
#define int long long
#define Il inline
#define Rg register
#define Ri Rg int
#define fi first
#define se second
#define vec vector
#define pb push_back
#define IT ::iterator
#define p_que priority_queue
using namespace std;
//typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
const int N=1e6;
const db eps=1e-9,pi=acos(-1.0);
int n,K,m,a[N+5],nx[N+5],la[N+5],b[N+5],bn=0,ans=0,nn=0,g[N+5];
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>K>>m;nx[0]=1,la[n+1]=n;if(K==1){cout<<0;return 0;}
for(Ri i=1;i<=n;i++)cin>>a[i],nx[i]=i+1,la[i]=i-1;
for(Ri i=nx[0],c=1;i<=la[n+1];i=nx[i]){
if(a[i]==a[la[i]])c++;else c=1;
if(c==K){int p=la[i];for(Ri i=1;i<K;i++)p=la[p];nx[p]=nx[i],la[nx[i]]=p,i=p,c=1,ans+=K*m;}
}
//判断串内能不能消,用链表做
for(Ri i=nx[0];i<=la[n+1];i=nx[i])b[++bn]=a[i];
int pl=1,pr=bn,c=0,co=0,tmp=0;
while(pl<pr){
if(b[pl]==b[pr]){
co=b[pl];
if(b[pl+1]==b[pr])pl++,c++;
else if(b[pr-1]==b[pl])pr--,c++;
else if(c+1==K)pl++,c++;
else{
c+=2,pl++,pr--;
if(c^K)break;
}
if(c==K)ans+=K*(m-1),c=0,tmp++;
}else break;
}
while(c--)b[++pr]=co;
//删首尾,双指针做,如果多删了记录删的颜色补回来
for(Ri i=pl;i<=pr;i++)g[b[i]]++;
if(g[b[pl]]==(pr-pl+1)){
ans+=g[b[pl]]*m/K*K;
if(!(g[b[pl]]*m%K))ans+=K*tmp;
}
cout<<n*m-ans;
return 0;
}