jzoj6257. [Provincial Selection Simulation 8.9] Road Construction

Description
Insert picture description here

Input
Insert picture description here

Output
Insert picture description here

Sample Input
Sample Input 1
5
1 2 3 4 5
1 2
2 3
2 4
3 5

Sample Input 2
10
1 7 3 4 8 6 2 9 10 5
1 2
1 3
2 4
3 5
2 6
3 7
4 8
5 9
6 10

Sample Output
Sample Output 1
0
0
0
2

Sample Output 2
0
0
0
1
1
0
1
2
3

Data Constraint
Insert picture description here

answer

It can be found that the coloring operation is similar to LCT
and the time complexity of LCT (the total number of splay trees operated) is n log n, corresponding to this question is that the total operation color block is n log n,
so LCT maintains color + tree array is the answer

code

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define low(x) (x&-(x))
using namespace std;

struct type{
    
    
	int s,id;
} A[100001];
int tr[100001][4]; //2=size 3=color
int fa[100001];
int C[100001];
int p[100001][2];
long long Tr[100001];
int n,i,j,k,l,I,x,y;
long long ans;

bool cmp(type a,type b)
{
    
    
	return a.s<b.s;
}

void rot(int t)
{
    
    
	int Fa=fa[t],Fa2=fa[Fa],s,x,x2;
	
	x=tr[Fa][1]==t;
	x2=tr[Fa2][1]==Fa;
	
	s=tr[t][x^1];
	
	tr[t][3]=tr[Fa][3];
	tr[Fa][3]=0;
	
	tr[Fa][2]=tr[tr[Fa][x^1]][2]+tr[tr[t][x^1]][2]+1;
	tr[t][2]=tr[tr[t][x]][2]+tr[Fa][2]+1;
	
	fa[s]=Fa;
	tr[Fa][x]=s;
	
	fa[Fa]=t;
	tr[t][x^1]=Fa;
	
	fa[t]=Fa2;
	if (!tr[t][3])
	tr[Fa2][x2]=t;
}

void splay(int t)
{
    
    
	int Fa,Fa2;
	
	while (!tr[t][3])
	{
    
    
		Fa=fa[t];
		
		if (!tr[Fa][3])
		{
    
    
			Fa2=fa[Fa];
			
			if ((tr[Fa2][0]==Fa)^(tr[Fa][0]==t)==1)
			rot(t),rot(t);
			else
			rot(Fa),rot(t);
		}
		else
		rot(t);
	}
}

void change(int t,int s)
{
    
    
	while (t<=n)
	{
    
    
		Tr[t]+=s;
		t+=low(t);
	}
}

long long find(int t)
{
    
    
	long long ans=0;
	
	while (t)
	{
    
    
		ans+=Tr[t];
		t-=low(t);
	}
	
	return ans;
}

int main()
{
    
    
	freopen("road.in","r",stdin);
	freopen("road.out","w",stdout);
	
	scanf("%d",&n);
	fo(i,1,n)
	{
    
    
		scanf("%d",&C[i]);
		
		A[i].s=C[i];
		A[i].id=i;
	}
	
	sort(A+1,A+n+1,cmp);
	
	j=0;
	fo(i,1,n)
	{
    
    
		if (i==1 || A[i].s!=A[i-1].s)
		++j;
		C[A[i].id]=j;
	}
	
	fo(i,1,n)
	{
    
    
		tr[i][2]=1;
		tr[i][3]=C[i];
	}
	
	fo(I,2,n)
	{
    
    
		scanf("%d%d",&x,&y);
		
		l=0;
		
		i=x;
		j=0;
//		access
		while (i)
		{
    
    
			splay(i);
			
			tr[i][2]-=tr[tr[i][1]][2];
			tr[tr[i][1]][3]=tr[i][3];
			
			tr[i][1]=0;
			
			++l;
			p[l][0]=tr[i][3];
			p[l][1]=tr[i][2];
			
			if (j)
			{
    
    
				tr[i][1]=j;
				
				tr[j][3]=0;
				tr[i][2]+=tr[j][2];
			}
			
			j=i;
			i=fa[i];
		}
		tr[j][3]=C[y];
		fa[y]=x;
		
		ans=0;
		fo(i,1,l)
		{
    
    
			ans+=find(p[i][0]-1)*p[i][1];
			change(p[i][0],p[i][1]);
		}
		
		printf("%lld\n",ans);
		
		fo(i,1,l)
		change(p[i][0],-p[i][1]);
	}
}

Guess you like

Origin blog.csdn.net/gmh77/article/details/99046013