Codeforces Round #443 (Div. 2)--D. Teams Formation--思维

D. Teams Formation

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard 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 npassenger 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

Copy

4 2 5
1 2 3 1

output

Copy

12

input

Copy

1 9 10
1

output

Copy

1

input

Copy

3 2 10
1 2 1

output

Copy

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.

参考题解https://blog.csdn.net/codeswarrior/article/details/80094168

还不是特别懂。

先对原来的串处理,处理出在这一个串中符合情况的,删除符合的子串。

然后对剩余的进行讨论,若l==r,则此时所有的串只包含一个字符。

否则,先看首尾数字相同的情况。

#include <algorithm>    //STL通用算法
#include <bitset>     //STL位集容器
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex>     //复数类
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>      //STL双端队列容器
#include <exception>    //异常处理类
#include <fstream>
#include <functional>   //STL定义运算函数(代替运算符)
#include <limits>
#include <list>      //STL线性列表容器
#include <map>       //STL 映射容器
#include <iomanip>
#include <ios>      //基本输入/输出支持
#include<iosfwd>     //输入/输出系统使用的前置声明
#include <iostream>
#include <istream>     //基本输入流
#include <ostream>     //基本输出流
#include <queue>      //STL队列容器
#include <set>       //STL 集合容器
#include <sstream>    //基于字符串的流
#include <stack>      //STL堆栈容器    
#include <stdexcept>    //标准异常类
#include <streambuf>   //底层输入/输出支持
#include <string>     //字符串类
#include <utility>     //STL通用模板类
#include <vector>     //STL动态数组容器
#include <cwchar>
#include <cwctype>
#define ll long long
using namespace std;
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define dep(i,a,b) for(register int i=(a);i>=(b);i--)
//priority_queue<int,vector<int>,less<int> >q;
int dx[]= {-1,1,0,0,-1,-1,1,1};
int dy[]= {0,0,-1,1,-1,1,1,-1};
const int maxn = 100000+6;
const ll mod=1e9+7;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
ll a[maxn];
pair<ll,ll>s[maxn];
int main()
{
    int n,k,m;
    while(scanf("%d %d %d",&n,&k,&m)!=EOF)
    {
        rep(i,1,n)scanf("%lld",&a[i]);
        int top=0;
        rep(i,1,n)
        {
            if(!top||s[top].first!=a[i])
            {
                s[++top]=make_pair(a[i],1);
            }
            else
            {
                s[top].second=(s[top].second+1)%k;
            }
            if(s[top].second==0)
                top--;
        }
        ll ans1=0;
        rep(i,1,top)
        {
            ans1+=s[i].second;
        }
        int l=1,r=top;
        ll ans2=0;
        while(l<r&&s[l].first==s[r].first&&(s[l].second+s[r].second)%k==0)
        {
            ans2+=s[l].second+s[r].second;
            l++;
            r--;
        }
        ll ans=0;
        if(l==r)
        {
            if(s[l].second*m%k==0)
            {
                ans+=m*ans1-m*ans2-s[l].second*m;
            }
            else
            {
                ans+=m*ans1-(m-1)*ans2-s[l].second*m/k*k;
            }
        }else
        {
            if(s[l].first==s[r].first)
            {
                ans2+=(s[l].second+s[r].second)/k*k;
            }
            ans=m*ans1-ans2*(m-1);
        }
        printf("%lld\n",ans);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值