题目链接:传送门
主席树模板题。
把子弹按照
x
x
x排序,另外记录一个
t
t
t,表示子弹射♂出去的时间qwq。
对于每块木板,设它左右端的
x
x
x坐标分别为
x
1
,
x
2.
x1,x2.
x1,x2.
二分查找出子弹在
[
x
1
,
x
2
]
[x1,x2]
[x1,x2]区间内的部分,记为
[
l
,
r
]
[l,r]
[l,r]。
因为子弹是按照时间顺序射♂出去的,所以问题就转化为在
[
l
,
r
]
[l,r]
[l,r]区间内求第
s
s
s小值。
然后上主席树板子即可。
注:如果
[
l
,
r
]
[l,r]
[l,r]区间长度小于当前木板的
s
s
s,要
c
o
n
t
i
n
u
e
continue
continue掉qwq
代码
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<math.h>
#include<vector>
#define re register int
#define rl register ll
using namespace std;
typedef long long ll;
ll read() {
rl x=0,f=1;
char ch=getchar();
while(ch<'0' || ch>'9') {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9') {
x=10*x+ch-'0';
ch=getchar();
}
return x*f;
}
namespace I_Love {
const int Size=200005;
const int LOG=20;
int n,m,damage[Size];
struct plank {
int x1,x2,s;
} wood[Size];
struct bullet {
int x,t;
inline bool operator < (const bullet b) const {
return x<b.x;
}
inline bool operator < (const int b) const {
return x<b;
}
} jzm[Size]; //枪毙名单
inline bool operator < (const int a,const bullet b) {
return a<b.x;
}
int tot,T[Size],ls[Size*LOG],rs[Size*LOG],sum[Size*LOG];
int update(int pre,int l,int r,int v) {
int rt=++tot;
ls[rt]=ls[pre]; rs[rt]=rs[pre];
sum[rt]=sum[pre]+1;
if(l<r) {
int mid=(l+r)>>1;
if(v<=mid) {
ls[rt]=update(ls[pre],l,mid,v);
} else {
rs[rt]=update(rs[pre],mid+1,r,v);
}
}
return rt;
}
int query(int u,int v,int l,int r,int k) {
if(l==r) return l;
int mid=(l+r)>>1,num=sum[ls[v]]-sum[ls[u]];
if(k<=num) return query(ls[u],ls[v],l,mid,k);
return query(rs[u],rs[v],mid+1,r,k-num);
}
void Fujibayashi_Ryou() {
// damage[1]=1; damage[2]=3; damage[3]=4; damage[4]=6;
// printf("%d\n",damage[upper_bound(damage+1,damage+1+4,6)-damage-1]);
n=read();
m=read();
for(re i=1; i<=n; i++) {
wood[i].x1=read();
wood[i].x2=read();
wood[i].s=read();
}
for(re i=1; i<=m; i++) {
jzm[i].x=read();
jzm[i].t=i;
}
sort(jzm+1,jzm+1+m);
for(re i=1; i<=m; i++) {
T[i]=update(T[i-1],1,m,jzm[i].t);
}
for(re i=1; i<=n; i++) {
int pre=lower_bound(jzm+1,jzm+1+m,wood[i].x1)-jzm;
int suf=upper_bound(jzm+1,jzm+1+m,wood[i].x2)-jzm-1;
if(suf-pre+1<wood[i].s) continue;
damage[query(T[pre-1],T[suf],1,m,wood[i].s)]++;
}
for(re i=1; i<=m; i++) {
printf("%d\n",damage[i]);
}
}
}
int main() {
I_Love::Fujibayashi_Ryou();
return 0;
}