Codeforces Round #443 (Div. 2)D. Teams Formation详解

来源:互联网 发布:平面广告图制作软件 编辑:程序博客网 时间:2024/05/22 21:32

D. Teams Formation
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
This time the Berland Team Olympiad in Informatics is held in a remote city that can only be reached by one small bus. Bus has n passenger seats, seat i can be occupied only by a participant from the city ai.

Today the bus has completed m trips, each time bringing n participants. The participants were then aligned in one line in the order they arrived, with people from the same bus standing in the order of their seats (i. e. if we write down the cities where the participants came from, we get the sequence a1, a2, …, an repeated m times).

After that some teams were formed, each consisting of k participants form the same city standing next to each other in the line. Once formed, teams left the line. The teams were formed until there were no k neighboring participants from the same city.

Help the organizers determine how many participants have left in the line after that process ended. We can prove that answer doesn’t depend on the order in which teams were selected.

Input
The first line contains three integers n, k and m (1 ≤ n ≤ 105, 2 ≤ k ≤ 109, 1 ≤ m ≤ 109).

The second line contains n integers a1, a2, …, an (1 ≤ ai ≤ 105), where ai is the number of city, person from which must take seat i in the bus.

Output
Output the number of remaining participants in the line.

Examples
input
4 2 5
1 2 3 1
output
12
input
1 9 10
1
output
1
input
3 2 10
1 2 1
output
0
Note
In the second example, the line consists of ten participants from the same city. Nine of them will form a team. At the end, only one participant will stay in the line.
题意:给出长度为n的串,重复m次,其中连续出现k次的可以消掉。问最终为多长的序列。
思路:一开始没想出来什么很好的想法。最后的做法也没什么算法,相当于高级模拟题吧。
首先,一个串中出现k次的可以消掉,把一个串清除干净后,和另一个串连接起来可能会删除一些。
那么最终的序列是左边+m次*中间+右边。
最后看一下不同的情况,中间的如果是同种颜色,那么又会消掉一些,如果刚好是k的倍数,那么当中间的消完后,左边和右边也会消掉。最后结果就是0,如果不是k的倍数,那么就是左边+右边+m*len%k
如果中间的不是同种颜色,那么结果就是左边+右边+m*len。
代码如下:

#include<bits/stdc++.h>using namespace std;int a[100005];int Real[100005];int n,k,m;int L,R;int landr=0;int sum[100005];void remove(){    int now=1;    int thesum=0;    int realnow=1;    for(int i=1;i<=n;i++)    {        Real[realnow++]=a[i];        if(Real[realnow-1]!=Real[realnow-2])            sum[realnow-1]=1;        else            sum[realnow-1]=sum[realnow-2]+1;        if(sum[realnow-1]==k)        {            realnow-=k;        }    }    L=1,R=realnow-1;    while(1)    {        int l=L,r=R;        int cnt=0;        while(l<r&&Real[l]==Real[r]&&cnt<k)        {            l++;            cnt++;        }        while(l<r&&Real[r]==Real[R]&&cnt<k)        {            r--;            cnt++;        }        if(cnt==k)        {            L=l;            R=r;            landr+=k;        }        else            break;    }}void solve(){    bool flag=true;    for(int i=L;i<=R;i++)        if(Real[i]!=Real[L])    {        flag=false;        break;    }    if(flag)    {        int midsum=1LL*(R-L+1)*m%k;        if(midsum==0)        {            printf("0\n");        }        else        {            printf("%lld\n",1LL*landr+1LL*midsum);        }    }    else    {        int midsum=R-L+1;        printf("%lld\n",1LL*landr+1LL*midsum*m);    }}int main(){    cin>>n>>k>>m;    for(int i=1;i<=n;i++)        scanf("%d",&a[i]);    remove();    solve();}
原创粉丝点击