题目链接: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;
}