# Luogu P5351 Ruri Loves Maschera

CODE

#include<cstdio>
#include<cctype>
#include<algorithm>
#define RI int
#define CI const int&
#define Tp template <typename T>
using namespace std;
typedef long long LL;
const int N=100005,INF=1e9;
struct edge
{
int to,nxt,v;
}e[N<<1]; int n,head[N],rst[N],num,cnt,L,R,x,y,z; LL ans; bool flag;
class FileInputOutput
{
private:
static const int S=1<<21;
char Fin[S],*A,*B;
public:
{
x=0; char ch; while (!isdigit(ch=tc()));
while (x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));
}
#undef tc
}F;
inline int min(CI a,CI b)
{
return a<b?a:b;
}
inline void addedge(CI x,CI y,CI z)
{
}
namespace Case1 //Point Division Solver
{
class Tree_Array
{
private:
int size[N]; LL sum[N]; bool vis[N];
public:
#define lowbit(x) x&-x
inline void add(CI x,CI y,CI opt,RI i=0)
{
for (i=x;i<=num;i+=lowbit(i)) size[i]+=opt;
for (i=x;i;i-=lowbit(i)) sum[i]+=opt*y;
}
inline int query_rk(RI x,int ret=0)
{
for (;x;x-=lowbit(x)) ret+=size[x]; return ret;
}
inline LL query_sum(RI x,LL ret=0)
{
for (;x<=num;x+=lowbit(x)) ret+=sum[x]; return ret;
}
#undef lowbit
}BIT;
#define to e[i].to
class Point_Division_Solver
{
private:
struct data
{
int dep,mxv;
friend inline bool operator < (const data& A,const data& B)
{
return A.dep<B.dep;
}
}s[N]; int size[N],tot,pl[N],pr[N]; bool vis[N];
inline int max(CI a,CI b)
{
return a>b?a:b;
}
inline void maxer(int& x,CI y)
{
if (y>x) x=y;
}
inline void DFS(CI now,CI fa,CI d,CI mx)
{
s[++tot]=(data){d,mx}; if (L<=d&&d<=R) ans+=rst[mx];
if (to!=fa&&!vis[to]) DFS(to,now,d+1,max(mx,e[i].v));
}
public:
int mx[N],ots,rt;
inline void getrt(CI now,CI fa=1)
{
size[now]=1; mx[now]=0;
getrt(to,now),size[now]+=size[to],maxer(mx[now],size[to]);
if (maxer(mx[now],ots-size[now]),mx[now]<mx[rt]) rt=now;
}
inline void solve(CI now)
{
RI i,j; vis[now]=1; tot=0; int lst=0;
{
DFS(to,now,1,e[i].v); sort(s+lst+2,s+tot+1); if (lst)
{
int p1=lst; for (j=lst+1;j<=tot;++j)
{
while (p1&&s[p1].dep+s[j].dep>R) --p1; pr[j]=p1;
}
int p2=1; for (j=tot;j>lst;--j)
{
while (p2<=lst&&s[p2].dep+s[j].dep<L) ++p2; pl[j]=p2;
}
p1=lst+1; p2=lst; for (j=lst+1;j<=tot;++j)
{
ans+=1LL*BIT.query_rk(s[j].mxv)*rst[s[j].mxv]+BIT.query_sum(s[j].mxv+1);
}
}
lst=tot; sort(s+1,s+lst+1);
}
mx[rt=0]=INF,ots=size[to],getrt(to,now),solve(rt);
}
}PD;
#undef to
inline void solve(void)
{
sort(rst+1,rst+n); num=unique(rst+1,rst+n)-rst-1;
for (RI i=1;i<=cnt;++i) e[i].v=lower_bound(rst+1,rst+num+1,e[i].v)-rst;
PD.mx[PD.rt=0]=INF; PD.ots=n; PD.getrt(1); PD.solve(PD.rt);
}
};
namespace Case2 //Flower Graph Solver
{
inline void solve(void)
{
RI i; sort(rst+1,rst+n); if (L<=1&&1<=R)
for (i=1;i<n;++i) ans+=rst[i]; if (L<=2&&2<=R)
for (i=1;i<n;++i) ans+=1LL*rst[i]*(i-1);
}
};
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);