rt。可持久化线段书加倍增。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define LL long long
int n , m , inw[200050] , Nans(0) , ft[200050] , lg[200050] , fa[200050][21];
struct Woods {
int l , r , ks;
}a[200050];
struct Tree {
int l , r , pre;
Tree ()
{
l = r = pre = 0;
}
}t[400050*20];
int Nodes(0) , root[200050]{};
const int Tree_Size(200055);
int New (int x)
{
++ Nodes;
t[Nodes] = t[x];
return Nodes;
}
int Update (int x , int l , int r , int xy)
{
x = New (x);
++ t[x].pre;
if(l == r) return x;
int mid = (l+r)>>1;
if(xy <= mid) t[x].l = Update (t[x].l , l , mid , xy);
if(mid+1 <= xy) t[x].r = Update (t[x].r , mid+1 , r , xy);
return x;
}
int Query (int x , int l , int r , int L , int R)
{
if (L <= l && r <= R) return t[x].pre;
int mid = (l+r)>>1;
int ans(0);
if(L <= mid) ans += Query (t[x].l , l , mid , L , R);
if(mid+1 <= R) ans += Query (t[x].r , mid+1 , r , L , R);
return ans;
}
int Ladd (int r , int k)
{
for(int i = lg[r] ; i >= 0 ; i --)
{
int p = Query (root[fa[r][i]] , 1 , Tree_Size , a[k].l , a[k].r);
// printf("\nLadd --> r = %d k = %d i = %d fa = %d root = %d al = %d ar = %d\n",r,k,i,fa[r][i],root[fa[r][i]],a[k].l,a[k].r);
if(p >= a[k].ks) r = fa[r][i];
// printf("List --> p = %d aks = %d New r = %d\n\n",p,a[k].ks,r);
if(r == 1) return 1;
}
return r;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1 ; i <= n ; i ++)
{
scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].ks);
}
for(int i = 1 ; i <= m ; i ++)
{
scanf("%d",&inw[i]);
root[i] = root[i-1];
root[i] = Update (root[i] , 1 , Tree_Size , inw[i]);
}
for(int i = 1 ; i <= m+5 ; i ++)
{
lg[i] = lg[i-1] + int(1 << (lg[i-1]+1) == i);
fa[i][0] = i-1;
for(int j = 1 ; j <= lg[i]+1 ; j ++)
{
fa[i][j] = fa[fa[i][j-1]][j-1];
}
}
for(int i = 1 ; i <= n ; i ++)
{
int g = Ladd (m+1 , i);
++ ft[g];
// printf("i = %d g = %d ft[g=%d] = %d\n",i,g,g,ft[g]);
}
for(int i = 1 ; i <= m ; i ++)
{
printf("%d\n",ft[i]);
}
return 0;
}