Teams Formation
题目链接:CodeForces - 878B题意:给出有n个数的序列, 将该序列重复m次, 如果有k个连续的相同的数, 去掉这k个数, 直到没有连续的相同的k个数为止, 问最后还有几个数?
首先, 我们先把原序列中有的连续的相同的k个数删去,
如果一个序列重复一次, 那么会是他的尾和首相接, 我们需要删去首尾相接后的连续的相同的k个数;
重复m次, 即有m-1次首尾相接;
注意用long long;
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int maxn = 1e5+10;
pair<long long, long long> sp[maxn];
long long a[maxn];
long long rec, rec1, ans, l, r;
int main(){
int n, m, k, top=0;
scanf("%d%d%d", &n, &k, &m);
for(long long i=0; i<n; i++) scanf("%lld", &a[i]);
for(long long i=0; i<n; i++){//删掉原序列中连续的相同的k个数
if(!top||sp[top].first!=a[i]) sp[++top]=make_pair(a[i], 1);
else sp[top].second = (sp[top].second+1)%k;
if(sp[top].second==0) top--;
}
rec=rec1=ans=0;
l=1, r=top;
for(long long i=1; i<=top; i++) rec+=sp[i].second;//rec为原序列还剩多少数
while(l<r && sp[l].first==sp[r].first && (sp[l].second+sp[r].second)%k==0)//计算首尾相接时应删去的数的个数
rec1+=sp[l].second+sp[r].second, l++, r--;
if(l==r){
if(sp[l].second*m%k==0)
ans-=rec1;
ans+=rec*m-rec1*(m-1)-sp[l].second*m/k*k;
}
else{
if(sp[l].first==sp[r].first)
rec1+=(sp[l].second+sp[r].second)/k*k;
ans=rec*m-rec1*(m-1);
}
printf("%lld\n", ans);
return 0;
}