bzoj4569 [Scoi2016] Meng Meng Da and search collection + st list

This question is very clever, it describes a new delayed label relationship. .

A normal line segment tree uses a space of n*4 to describe a sequence, so for an interval, there may be log points corresponding to one point

The line segment tree uses the smallest possible space to make the query log

The st table is the space of nlogn. For a range of intervals, one-to-one correspondence can be achieved. It is just preprocessing that is more violent than the line segment tree.

So if you want to put this question on the line segment tree, you need to split the two intervals, and update the father array on the node of the line segment tree.

The scattered points may be log^2, and it is troublesome to mark the points

In the case of the st table, since the interval length is one-to-one correspondence, only two marks are needed, and the overlapping marks are combined with a union search.

Then it is equivalent to the single-point query operation of the enumeration of the line segment tree, layer by layer pushdown (not layer by layer, but troublesome)

The optimization of this question for the violent union search set is to use the union search set for the interval as well, and use the superposition of delayed markers to reduce repetitive operations.


code:

#include<iostream>
#include<cstdio>
#define P 1000000007
using namespace std;
int f[100005][25],o,n,m,i,j,er[25],l1,l2,r1,r2,cnt,ans;
int zhao(int o,int x)
{
	if(f[o][x]!=o)f[o][x]=zhao(f[o][x],x);
	return f[o][x];
}
int main()
{
scanf("%d%d",&n,&m);
er[0]=1;
for(i=1;i<=20;i++)er[i]=er[i-1]*2;
for(i=1;i<=n;i++)
for(j=0;j<=20;j++)
f[i][j]=i;
for(j=1;j<=m;j++)	
	{
		scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
		int o=r1-l1+1;
		for(i=0;i<=20;i++)
		if(er[i]&o) 
		{
	int f1=zhao(f[l1][i],i),f2=zhao(f[l2][i],i);		
    if(f1!=f2)f[f1][i]=f2;
l1+=er[i];
l2+=er[i];   			
		}
	}
	for(j=20;j>=1;j--)
	{
		for(i=1;i<=n;i++)
{
	//分下去	
	if(i+er[j]-1>n)continue;
o=zhao(i,j);
	int ll=zhao(o,j-1);
	int lll=zhao(i,j-1);
	f[ll][j-1]=lll;	
	int rr=zhao(o+er[j-1],j-1);
	int rrr=zhao(i+er[j-1],j-1);
	f[rr][j-1]=rrr;
}				
	}
	for(i=1;i<=n;i++)
	if(zhao(i,0)==i)++cnt;
	ans=9;
	for(i=1;i<cnt;i++)
	ans=1ll*ans*10%P;
	printf("%d",ans);
}



Guess you like

Origin blog.csdn.net/haobang866/article/details/79263706