C. Store

C. Store

time limit per test 1.0 s

memory limit per test 256 MB

input standard input

output standard output

Ichuan is a store owner and his store has n products, numbered from 1 to n

Recently, his business is not very good, and he can occasionally sell a product, so he will confirm the information of the products sold.

MXY,it means that on the Xth day, the product numbered Yis sold.

DXY,in currently sold products, those whose number is greater than or equal to Y, which one is the lowest number which sold before the Xth day (including Xth day) .

Input

the first line contains two positive integers N,Q(2≤N,Q≤200000),which are the number of products and operations.

The following Q lines, each line contains one operator character (Mor D) and two integers x,y.(1≤x≤109,1≤y≤n)

Output

For each request of type DXY,output the number of required product. If no such product exists, output −1.

Examples

Input

3 4
M 10 3
M 5 1
D 20 2
D 5 1

Output

3
1

Input

10 10
M 20 10
D 1 9
M 2 3
D 17 10
M 20 2
D 8 2
M 40 1
D 25 2
M 33 9
D 37 9

Output

-1
-1
3
2
9

题目意思为有n件物品 m个操作

MXY 代表在时间x可以卖掉一个序号为y的物品

DXY 代表要卖掉一个时间在X以内序号在Y以上的物品  输出序号最小的一个物品的序号

通过线段树加二分的方法来解决问题

先建立一个线段树 所有的值都是最大值

树的最下面一排的值即为每个序号的数可以卖出去的时间   根为这个区间可以卖出去的最小时间

每一个M都更新一次线段树

当出现了一个D后就开始用二分查找 查找到满足条件的最小序号

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
char a[3];
int n,m,b,c,f[800005];
void update(int res,int l,int r,int t,int p)//找到序号p的地方 把这个序号的时候的值赋为t 
{
	if(l==r)//找到了这个点 
	{
		f[res]=t;
		return;
	}
	int mid=(l+r)/2;
	if(p<=mid)//这个点在左边 
	{
		update(res*2,l,mid,t,p);
	}
	if(p>mid)//这个点在右边 
	{
		update(res*2+1,mid+1,r,t,p);
	}
	f[res]=min(f[res*2],f[res*2+1]);//更新线段树上的值 
}
int query(int res,int l,int r,int L,int R)//求出区间L到R的序号里最小的时间 
{
	if(L<=l&&r<=R)//这个区间被要超找的区间包含 
	{
		return f[res];//直接放回这个区间的最小值 
	}
	int mid=(l+r)/2;
	int ans=INF;
	if(L<=mid) ans=min(ans,query(res*2,l,mid,L,R));//有一部分在左边 
	if(R>=mid+1) ans=min(ans,query(res*2+1,mid+1,r,L,R));//有一部分在右边 
	return ans;
}
int find(int v,int l,int r)
{
	int ans=-1;//没有的话就输出-1 所以把ans赋初值-1 
	while(l<=r)//二分 
	{
		int mid=(l+r)/2;
		if(query(1,1,n,l,mid)<=v)//找左边有没有数满足时间小于V  有就继续在左边找 没有就在右边二分找 
		{
			r=mid-1;
			ans=mid;
		}
		else 
		l=mid+1;
	}
	return ans;
}
int main()
{
	scanf("%d %d",&n,&m);
	for(int i=0;i<=n*4;i++)
	f[i]=INF;//刚开始树里面都是最大值 
	for(int i=1;i<=m;i++)
	{
		getchar();
		scanf("%s %d %d",a,&b,&c);
		if(a[0]=='M')
		{
			update(1,1,n,b,c);//更新 
		}
		else if(a[0]=='D')
		{
			printf("%d\n",find(b,c,n));//查找 
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/tjndsg/article/details/89102262
今日推荐