题意: 现在有n条火车, 每条火车都有一个运行 [ Li, Ri ], 现在有m支火箭队, 每次火箭队都会破坏这整条铁路上的一个点, 如果一条火车的运行区间[Li, Ri] 被破坏了, 那么这条火车会立刻停止。
题解:线段树, 先将所有火车的左右端点排好序, 然后每一个叶子节点都是一个火车的区间, 每一颗子树的根节点都保存着子树内所有火车的运行区间的最左边的点 还有 最右边的点,然后xjb乱找, 如果找到一条火车被破坏了, 那我们就将这条火车的左端点改成 inf 右端点改成 -inf, 这样就不会对接下来的操作产生影响。
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = ;
const int N = 4e5 + ;
int L[N], R[N], id[N], ans[N];
int lmin[N<<], rmax[N<<];
int t;
bool cmp(int x, int y){
if(L[x] == L[y]) return R[x] < R[y];
return L[x] < R[y];
}
/*bool cmp(int x, int y){
return L[x] + R[x] < L[y] + R[y];
}*/
void Push_UP(int rt){
lmin[rt] = min(lmin[rt<<], lmin[rt<<|]);
rmax[rt] = max(rmax[rt<<], rmax[rt<<|]);
}
void Build(int l, int r, int rt){
if(l == r){
lmin[rt] = L[id[l]];
rmax[rt] = R[id[l]];
return ;
}
int m = l+r >> ;
Build(lson);
Build(rson);
Push_UP(rt);
}
LL res = ;
int Update(int l, int r, int rt, int x){
if(x > rmax[rt] || x < lmin[rt]) return ;
if(l == r){
rmax[rt] = -inf;
lmin[rt] = inf;
ans[id[l]] = t;
res = id[l] * res % mod;
return ;
}
int m = l+r >> ;
int a = Update(lson, x) + Update(rson, x);
Push_UP(rt);
return a;
}
int main(){
int T;
scanf("%d", &T);
for(int _i = ; _i <= T; _i++){
int n, m;
res = ;
scanf("%d%d", &n, &m);
printf("Case #%d:\n", _i);
for(int i = ; i <= n; i++){
scanf("%d%d", &L[i], &R[i]);
id[i] = i; ans[i] = ;
}
sort(id+, id++n, cmp);
Build(, n, );
for(t = ; t <= m; t++){
int x;
scanf("%d", &x);
x ^= res, res = ;
//cout << x << endl;
int cc = Update(,n,,x);
if(!cc) res = ;
printf("%d\n", cc);
}
for(int i = ; i <= n; i++)
printf("%d%c", ans[i], " \n"[i==n]);
}
return ;
}