牛客网多校第六场I题 - Team Rocket(线段树)

题目链接:https://www.nowcoder.com/acm/contest/144/I

这篇还是写转载把。。。大部分代码都是照大佬的博客抄的。。。

转载地址:http://www.cnblogs.com/Jadon97/p/9432236.html(以下分析摘抄大佬博客)

题意:
给定n个区间, m次询问, 每次询问给一个点, 问这个点在哪些区间内, 然后删掉这些区间。
分析:
将n个区间按L大小升序排列, 然后将这些区间视为点构建一棵n个点的线段树, 树的节点记录这个区间的[l, r] 和按题目输入顺序排列的index
只有叶子节点的l, r代表这个区间本身, 他们的父亲更新他们儿子的最大r用于剪枝 (如果这个点所有儿子的最大R都小于查询的点, 就不用查了)
接下来只要二分出左区间大于x的那个区间的pos, 那么查询区间就是(1~pos)中有哪些点的右区间大于x, 记录答案并修改右区间即可。 

代码(结合我自己的模板)

#include<bits/stdc++.h>
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int INF=2e9+10;
typedef struct Train
{
	int l,r;
	int ind;
    bool operator < (const Train &a) const{
	return l<a.l;
    }
}  Train;
Train t[maxn];
Train tree[maxn*4];
int x,y,pos,cancel;
int e;
ll res;
int ans[maxn];
//bool cmp(Train &a,Train &b)
//{
//	if(a.l!=b.l)
//	return a.l<b.l;
//	return a.r<b.r;
//}
void PushUP(int rt) 
{
       tree[rt].r = max(tree[rt<<1].r , tree[rt<<1|1].r);
}
void build(int l,int r,int rt) {
       if (l == r) 
	   {
	      tree[rt].l=t[l].l;
	      tree[rt].r=t[l].r;
	      tree[rt].ind=t[l].ind;
		  return ;
	   }
       int m = (l + r) >> 1;
       build(lson);
       build(rson);
       PushUP(rt);
}
//void b_search(int l,int r)
//{
//	while(l<=r)
//	{
//		int mid=l+(r-l)/2;
//		if(t[mid].ind>x)
//		{
//		   pos=min(pos,mid);
//		   r=mid-1;
//	    }
//	    else
//	    {
//	    	l=mid+1;
//		}
//	}
//}
void query(int l,int r,int rt) {
       if(tree[rt].r < x)
       return ;
	   if (l == r) 
	   {
            cancel++;
			int tem=tree[rt].ind;
			res=(ll)(res*tem)% 998244353;
			tree[rt].r=-INF;
			ans[tem]=e;
            return ;
       }
       int m = (l + r) >> 1;
       query(lson);
       if(pos>m)
	   query(rson);
       PushUP(rt);
}
int main()
{
	int T;
	int n,m;
	scanf("%d",&T);
	for(int kase=1;kase<=T;kase++)
	{
		printf("Case #%d:\n", kase);
		scanf("%d%d",&n,&m);
		memset(ans,0,sizeof(ans));
		for(int i=1;i<=n;i++)
		{
		   scanf("%d%d",&t[i].l,&t[i].r);
		   t[i].ind=i;
	    }
	    sort(t+1,t+1+n);
	    build(1,n,1);
	    res=0;
	    for(e=1;e<=m;e++)
	    {
	    	scanf("%d",&y);
	    	x=y^res;
	    	pos = upper_bound(t + 1, t + 1 + n, (Train) {x,0,0}) - (t + 1);
	    	cancel=0,res=1;
	    	if(pos>0)
	    	query(1,n,1);
	    	printf("%d\n",cancel);
	    	if(!cancel)
	    	res=0;
		}
		printf("%d",ans[1]);
		for(int i=2;i<=n;i++)
		printf(" %d",ans[i]);
		printf("\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/star_moon0309/article/details/81490723