hack 数据已过.
把子弹排序后塞进线段树,每个子弹都新开一个版本,pl 和 pr 分别维护对应区间能取的左边界和右边界,每次查询查询 pr[line[i].r] 和 pl[line[i].l]-1 作差之后的树上的第 line[i].s 大.
code:
// Author:zymooll
#include<bits/stdc++.h>
#define getchar getchar_unlocked
#define putchar putchar_unlocked
#define int long long
using namespace std;
int read(){
int s=0,w=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')w=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
s=s*10+c-'0';
c=getchar();
}
return s*w;
}
void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>=10)print(x/10);
putchar(x%10+'0');
return;
}
const int NMax=2e5;
int n,m;
struct Node{
int n,l,r;
}t[(NMax<<5)+10];
int ncnt;
int root[NMax+10];
int clone(int p){
t[++ncnt]=t[p];
return ncnt;
}
int build(int L,int R){
int p=++ncnt;
if(L==R)return p;
int mid=(L+R)/2;
t[p].l=build(L,mid);
t[p].r=build(mid+1,R);
return p;
}
int modify(int tl,int L,int R,int x){
int tr=clone(tl);
t[tr].n++;
if(L==R)return tr;
int mid=(L+R)/2;
if(x<=mid)t[tr].l=modify(t[tl].l,L,mid,x);
else t[tr].r=modify(t[tl].l,mid+1,R,x);
return tr;
}
int ask(int tl,int tr,int L,int R,int x){
if(L==R)return L;
int mid=(L+R)/2,rk=t[t[tr].l].n-t[t[tl].l].n;
if(x<=rk)return ask(t[tl].l,t[tr].l,L,mid,x);
else return ask(t[tl].r,t[tr].r,mid+1,R,x-rk);
}
struct Line{
int l,r,s;
}line[NMax+10];
struct Ammo{
int x,id;
friend bool operator < (Ammo aa,Ammo bb){
return aa.x^bb.x?aa.x<bb.x:aa.id<bb.id;
}
}ammo[NMax+10];
int pl[NMax+10],pr[NMax+10];
int ans[NMax+10];
signed main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
n=read(),m=read();
for(int i=1;i<=n;i++){
line[i].l=read(),line[i].r=read(),line[i].s=read();
}
for(int i=1;i<=m;i++){
ammo[i].x=read(),ammo[i].id=i;
}
sort(ammo+1,ammo+1+m);
for(int i=1;i<=m;i++){
if(!pl[ammo[i].x])pl[ammo[i].x]=i;
pr[ammo[i].x]=i;
}
for(int i=1;i<=NMax;i++){
if(!pr[i])pr[i]=pr[i-1];
}
for(int i=NMax;i>=1;i--){
if(!pl[i])pl[i]=pl[i+1];
}
root[0]=build(1,NMax);
for(int i=1;i<=m;i++){
root[i]=modify(root[i-1],1,NMax,ammo[i].id);
}
for(int i=1;i<=n;i++){
if(pr[line[i].r]-pl[line[i].l]+1<line[i].s)continue;
ans[ask(root[pl[line[i].l]-1],root[pr[line[i].r]],1,NMax,line[i].s)]++;
}
for(int i=1;i<=m;i++){
print(ans[i]),putchar('\n');
}
return 0;
}