nlog^2n求优化
查看原帖
nlog^2n求优化
1098596
WhiteNight__楼主2024/11/20 14:19

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;
}
2024/11/20 14:19
加载中...