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; }