• [COCI2017-2018#1] Deda


    Description

    • 小马里卡正在创作一个奇妙的童话故事。她一边编故事,一边讲给她的爷爷听。爷爷可高兴了,于是问了她一些有趣的问题。
    • 在小马里卡的故事中,有N个年龄分别为1~N岁的孩子(最小的1为岁,最大的为N岁)。有一天,她们一起乘火车出去旅行。铁路线上有好多个车站,分别以0, 1, 2, 3……编号。其中第0站为始发站,火车每到一个车站都会停下来逗留一段时间。每个孩子都可以在选择自己喜欢的车站下车。
    • 小马里卡喜欢这样讲述她的故事:“在第X站,年龄为A岁的孩子下车了。”不过小马里卡的习惯非常不好,她讲述故事的顺序是完全随机的。换句话说,X是不单调的。爷爷知道小马里卡的坏习惯,所以他喜欢时不时问一些有趣的问题来找小马里的麻烦。问题是这样的:“年龄大于等于B且在第Y站(包含第Y站)以前下车的最年轻的小孩是多大?”
    • 小马里卡必须正确回答爷爷的问题,否则爷爷会因生气而睡觉。值得注意的是,小马里卡的答案必须在当时是正确的。虽然小马里卡在随后的讲述中可能会改变问题的答案,但这都是无关紧要的。
    • 小马里卡对自己的坏习惯十分无奈。由于故事的顺序过于杂乱,小马里卡根本无法正确回答爷爷的问题。于是她找到了聪明的你。请帮小马里卡编写一个程序,动态追踪她的讲述,并回答爷爷的问题。

    Input

    • 输入的第一行包含两个正整数N,Q((2leqslant N,Qleqslant 200000)),分别代表孩子的数量和语句的数量。
    • 接下来Q行,每行一个语句。语句的格式为“M X A”或“D Y B”,分别代表小马里卡的讲述和爷爷的问题。其中M、D为大写字母,X、Y、A、B((1leqslant X,Yleqslant 1000000000,1leqslant A,Bleqslant N))分别为一个正整数。其意义请见Description。题目中保证至少有一个“D”。

    Output
    对于每一个问题D输出一个答案。答案为一个整数。如果爷爷的问题无解,请输出-1。

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

    Sample Output 1
    3
    1

    Sample Input 2
    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

    Sample Output 2
    -1
    -1
    3
    2
    9


    开始想到把车站离线离散化,然后每次查询(1sim y)区间内比(B)大的最小的年龄,结果发现完全无法查找。。。

    然后改一下思路,直接用年龄作为下标建立线段树,线段树节点存储该年龄下车的站点,这样还可以避免多个人在同一站下车的情况

    下车就是单点修改,查询的话,就在(Bsim n)年龄区间内找到一个满足条件的最小年龄。寻找的时候,如果区间内站点最小值比(y)大,就可以直接退出;同样,在查询时,如果左区间找到了答案,右区间也就不需要继续下去了。

    具体实现可以看看代码

    /*program from Wolfycz*/
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7f7f7f7f
    //using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline char gc(){
    	static char buf[1000000],*p1=buf,*p2=buf;
    	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
    }
    template<typename T>inline T frd(T x){
    	int f=1; char ch=gc();
    	for (;ch<'0'||ch>'9';ch=gc())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=gc())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    template<typename T>inline T read(T x){
    	int f=1;char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')	f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x<0)    putchar('-'),x=-x;
    	if (x>9)	print(x/10);
    	putchar(x%10+'0');
    }
    template<typename T>inline T min(T x,T y){return x<y?x:y;}
    template<typename T>inline T max(T x,T y){return x>y?x:y;}
    template<typename T>inline T Swap(T &x,T &y){T t=x; x=y,y=t;}
    const int N=2e5;
    struct S1{
    	#define ls (p<<1)
    	#define rs (p<<1|1)
    	int tree[N*4+10];
    	S1(){memset(tree,127,sizeof(tree));}
    	void Modify(int p,int l,int r,int x,int v){
    		if (l==r){
    			tree[p]=v;
    			return;
    		}
    		int mid=(l+r)>>1;
    		x<=mid?Modify(ls,l,mid,x,v):Modify(rs,mid+1,r,x,v);
    		tree[p]=min(tree[ls],tree[rs]);
    	}
    	int Query(int p,int l,int r,int L,int R,int x){
    		if (L<=l&&r<=R&&tree[p]>x)	return -1;
    		if (l==r)	return l;
    		int mid=(l+r)>>1,Ans=-1;
    		if (L<=mid)	Ans=Query(ls,l,mid,L,R,x);
    		if (R>mid&&Ans==-1)	Ans=Query(rs,mid+1,r,L,R,x);
    		return Ans;
    	}
    	#undef ls
    	#undef rs
    }ST;//Segment Tree
    int main(){
    	int n=read(0),m=read(0);
    	for (int i=1;i<=m;i++){
    		char ch[5]; scanf("%s",ch);
    		int x=read(0),y=read(0);
    		if (ch[0]=='M')	ST.Modify(1,1,n,y,x);
    		else	printf("%d
    ",ST.Query(1,1,n,y,n,x));
    	}
    	return 0;
    }
    
  • 相关阅读:
    index of rmvb mp3 rm突破站点入口下载
    人类智商一般在多少左右?爱因斯坦的智商是多少?
    UVALive 5102 Fermat Point in Quadrangle 极角排序+找距离二维坐标4个点近期的点
    ProgressDialog使用总结
    Js中的多条件排序,多列排序
    腾讯2014年实习生招聘笔试面试经历
    周根项《一分钟速算》全集播放&amp;下载地址
    中国大推力矢量发动机WS15 跨入 世界先进水平!
    探索Android中的Parcel机制(上)
    ORACLE uuid自己主动生成主键
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/13681959.html
Copyright © 2020-2023  润新知