https://www.nowcoder.com/acm/contest/144/I
题意:
给你n条l到r的线段。
在给你q个询问,每次给你一个x,可以切断线段,问你每次切段了多少线段。
不能离线做的。
POINT:
线段树保存最小的L,最大的R。就很简单的东西。
#include <bits/stdc++.h>
#define LL long long
#define lt x<<1
#define rt x<<1|1
using namespace std;
const int N = 2e5+33;
const int inf = 1e9+7;
const LL mod = 998244353;
int L[N<<2],R[N<<2];
int aim[N];
LL res=0;
struct node
{
int l,r;
LL id;
bool friend operator < (node a,node b)
{
return a.l<b.l;
}
}a[N];
void up(int x,int l,int r)
{
L[x]=min(L[lt],L[rt]);
R[x]=max(R[lt],R[rt]);
}
void build(int x,int l,int r)
{
if(l==r){
L[x]=a[l].l;
R[x]=a[l].r;
}else{
int mid = (l+r)>>1;
build(lt,l,mid);
build(rt,mid+1,r);
up(x,l,r);
}
}
vector<node>V;
void change(int x,int l,int r,LL pos)
{
if(pos<L[x]||pos>R[x]) return;
if(l==r){
V.push_back(a[l]);
L[x]=inf;
R[x]=-inf;
return;
}else{
int mid = (l+r)>>1;
change(lt,l,mid,pos);
change(rt,mid+1,r,pos);
up(x,l,r);
}
}
int main()
{
int T,cas=0;
scanf("%d",&T);
while(T--){
int n,m;
res=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i].l,&a[i].r);
a[i].id=i;
aim[i]=0;
}
// sort(a+1,a+1+n);
build(1,1,n);
printf("Case #%d:\n",++cas);
for(int i=1;i<=m;i++){
V.clear();
LL y;
scanf("%lld",&y);
LL x=y^res;
change(1,1,n,x);
printf("%d\n",V.size());
if(V.size()==0) res=0;
else{
res=1;
for(int j=0;j<V.size();j++){
res=(res*V[j].id)%mod;
aim[V[j].id]=i;
}
}
}
for(int i=1;i<=n;i++){
printf("%d%c",aim[i],i==n?'\n':' ');
}
}
return 0;
}