Codeforces 818D Multicolored Car【思维+线段树】

D. Multicolored Cars
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Alice and Bob got very bored during a long car trip so they decided to play a game. From the window they can see cars of different colors running past them. Cars are going one after another.

The game rules are like this. Firstly Alice chooses some color A, then Bob chooses some color B (A ≠ B). After each car they update the number of cars of their chosen color that have run past them. Let's define this numbers after i-th car cntA(i) and cntB(i).

  • If cntA(i) > cntB(i) for every i then the winner is Alice.
  • If cntB(i) ≥ cntA(i) for every i then the winner is Bob.
  • Otherwise it's a draw.

Bob knows all the colors of cars that they will encounter and order of their appearance. Alice have already chosen her color A and Bob now wants to choose such color B that he will win the game (draw is not a win). Help him find this color.

If there are multiple solutions, print any of them. If there is no such color then print -1.

Input

The first line contains two integer numbers n and A (1 ≤ n ≤ 105, 1 ≤ A ≤ 106) – number of cars and the color chosen by Alice.

The second line contains n integer numbers c1, c2, ..., cn (1 ≤ ci ≤ 106) — colors of the cars that Alice and Bob will encounter in the order of their appearance.

Output

Output such color B (1 ≤ B ≤ 106) that if Bob chooses it then he will win the game. If there are multiple solutions, print any of them. If there is no such color then print -1.

It is guaranteed that if there exists any solution then there exists solution with (1 ≤ B ≤ 106).

Examples
Input
4 1
2 1 4 2
Output
2
Input
5 2
2 2 4 5 3
Output
-1
Input
3 10
1 2 3
Output
4
Note

Let's consider availability of colors in the first example:

  • cnt2(i) ≥ cnt1(i) for every i, and color 2 can be the answer.
  • cnt4(2) < cnt1(2), so color 4 isn't the winning one for Bob.
  • All the other colors also have cntj(2) < cnt1(2), thus they are not available.

In the third example every color is acceptable except for 10.


题目大意:


现在有N辆车经过,A和B玩一个游戏,他们统计他们自己喜欢的颜色的车辆的个数。

一开始对手已经选好了颜色A.我们现在要选择一个颜色,使得Cnti(chose)>=Cnti(A);

这里Cnti()表示到位子i,该颜色出现的车辆个数。

如果存在多解,输出任意一个可行解即可。


思路:


我们构造出一颗线段树,记录每一种颜色都出现了多少次。

然后我们遍历这N辆车,对应如果出现C【i】==A的时候,我们对应在这棵树中所有位子都减1.表示我们希望找到一个大于等于0的位子存在。

如果我们出现C【i】!=A的时候,如果这个位子不是负数(即之前所有位子都没有出现过A颜色的车辆多于这种颜色的车辆的情况),那么对应这种颜色就可能是一个可行解,那么对应update(i,1);

最终我们在这1e6种颜色之中,找到一个>=0的任意颜色即可。


Ac代码:


#include<stdio.h>
#include<string.h>
using namespace std;
#define lson l,m,rt*2
#define rson m+1,r,rt*2+1
int tree[1212112*4];
int flag[1212112*4];
void pushdown(int l,int r,int rt)//向下维护树内数据
{
    if(flag[rt])//如果贪婪标记不是0(说明需要向下进行覆盖区间(或点)的值)
    {
        int m=(l+r)/2;
        flag[rt*2]+=flag[rt];
        flag[rt*2+1]+=flag[rt];
        tree[rt*2]+=(m-l+1)*flag[rt];//千万理解如何覆盖的区间值(对应线段树的图片理解(m-l)+1)是什么意识.
        tree[rt*2+1]+=(r-(m+1)+1)*flag[rt];
        flag[rt]=0;
    }
}
void pushup(int rt)
{
    tree[rt]=tree[rt<<1]+tree[rt<<1|1];
}
void build( int l ,int r , int rt )
{
	if( l == r )
	{
		tree[rt]=0;
		flag[rt]=0;
		return ;
	}
	else
	{
		int m = (l+r)>>1 ;
		build(lson) ;
		build(rson) ;
		pushup(rt) ;
		return ;
	}
}
int Query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        return tree[rt];
    }
    else
    {
        pushdown(l,r,rt);
        int m=(l+r)>>1;
        int ans=0;
        if(L<=m)
        {
            ans+=Query(L,R,lson);
        }
        if(m<R)
        {
            ans+=Query(L,R,rson);
        }
        return ans;
    }
}
void update(int L,int R,int c,int l,int r,int rt)
{
    if(L<=l&&r<=R)//覆盖的是区间~
    {
        tree[rt]+=c*((r-l)+1);//覆盖当前点的值
        flag[rt]+=c;//同时懒惰标记~!
        return ;
    }
    pushdown(l,r,rt);
    int m=(l+r)/2;
    if(L<=m)
    {
        update(L,R,c,lson);
    }
    if(m<R)
    {
        update(L,R,c,rson);
    }
    pushup(rt);
}
int main()
{
    int n,b;
    while(~scanf("%d%d",&n,&b))
    {
        int cntb=0;
        memset(tree,0,sizeof(tree));
        memset(flag,0,sizeof(flag));
        build(1,1000000,1);
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            if(x==b)
            {
                update(1,1000000,-1,1,1000000,1);
            }
            else
            {
                if(Query(x,x,1,1000000,1)>=0)
                {
                    update(x,x,1,1,1000000,1);
                }
            }
        }
        int ans=-1;
        for(int i=1;i<=1000000;i++)
        {
            if(i==b)continue;
            if(Query(i,i,1,1000000,1)>=0)
            {
                ans=i;
                break;
            }
        }
        printf("%d\n",ans);
    }
}













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值