主席树 WA 求助
查看原帖
主席树 WA 求助
289296
zymooll楼主2023/6/27 13:07

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;
}

2023/6/27 13:07
加载中...