Description
Input
Output
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
题解
可以发现染色操作类似LCT
而LCT的时间复杂度(操作的splay树总数)为n log n,对应本题就是总操作颜色块为n log n
所以LCT维护颜色+树状数组算答案
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]);
}
}