WA on #29 求调悬一关
查看原帖
WA on #29 求调悬一关
807774
_Wind_Leaves_ShaDow_楼主2024/10/16 08:17

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;
}
2024/10/16 08:17
加载中...