题意:https://ac.nowcoder.com/acm/contest/2995/E

给你一棵树,节点有权值,让你求所有路径max-min的和。

思路:

我们计算每个点的贡献,对于一个点,当它为某条路径的最大值是,一定在一个所有值<=它的连通块里。所有我们从小到大添边合并共享(两块的大小之积,不是和

最小值也同样处理。

  1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0);
  2 #include <cstdio>//sprintf islower isupper
  3 #include <cstdlib>//malloc  exit strcat itoa system("cls")
  4 #include <iostream>//pair
  5 #include <fstream>//freopen("C:\\Users\\13606\\Desktop\\Input.txt","r",stdin);
  6 #include <bitset>
  7 //#include <map>
  8 //#include<unordered_map>
  9 #include <vector>
 10 #include <stack>
 11 #include <set>
 12 #include <string.h>//strstr substr strcat
 13 #include <string>
 14 #include <time.h>// srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
 15 #include <cmath>
 16 #include <deque>
 17 #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
 18 #include <vector>//emplace_back
 19 //#include <math.h>
 20 #include <cassert>
 21 #include <iomanip>
 22 //#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
 23 #include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
 24 using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
 25 //******************
 26 clock_t __START,__END;
 27 double __TOTALTIME;
 28 void _MS(){__START=clock();}
 29 void _ME(){__END=clock();__TOTALTIME=(double)(__END-__START)/CLOCKS_PER_SEC;cout<<"Time: "<<__TOTALTIME<<" s"<<endl;}
 30 //***********************
 31 #define rint register int
 32 #define fo(a,b,c) for(rint a=b;a<=c;++a)
 33 #define fr(a,b,c) for(rint a=b;a>=c;--a)
 34 #define mem(a,b) memset(a,b,sizeof(a))
 35 #define pr printf
 36 #define sc scanf
 37 #define ls rt<<1
 38 #define rs rt<<1|1
 39 typedef pair<int,int> PII;
 40 typedef vector<int> VI;
 41 typedef unsigned long long ull;
 42 typedef long long ll;
 43 typedef double db;
 44 const double E=2.718281828;
 45 const double PI=acos(-1.0);
 46 const ll INF=(1LL<<60);
 47 const int inf=(1<<30);
 48 const double ESP=1e-9;
 49 const int mod=(int)1e9+7;
 50 const int N=(int)5e5+10;
 51
 52 int fa[N];
 53 int SZ[N];
 54 int Find(int x)
 55 {
 56     return (x==fa[x])?x:(fa[x]=Find(fa[x]));
 57 }
 58
 59 vector<vector<int> >G(N);
 60 pair<ll,int> a[N];
 61 bool vis[N];
 62
 63 void solve()
 64 {
 65     int n;
 66     sc("%d",&n);
 67     for(int i=1;i<=n;++i)fa[i]=i,sc("%lld",&a[i].first),a[i].second=i,G[i].clear();
 68     for(int i=1;i<=n-1;++i)
 69     {
 70         int u,v;
 71         sc("%d%d",&u,&v);
 72         G[v].push_back(u);
 73         G[u].push_back(v);
 74     }
 75     sort(a+1,a+1+n);
 76     mem(vis,0);
 77     for(int i=1;i<=n;++i)SZ[i]=1;
 78     ll ans=0;
 79     for(int i=1;i<=n;++i)
 80     {
 81         int now=a[i].second;
 82         vis[now]=1;
 83         int sz=G[now].size();
 84         for(int j=0;j<sz;++j)
 85         {
 86             int to=G[now][j];
 87             if(vis[to])
 88             {
 89                 ans=(ans+a[i].first*SZ[now]%mod*SZ[Find(to)]%mod)%mod;
 90                 SZ[now]+=SZ[Find(to)];
 91                 fa[Find(to)]=Find(now);
 92             }
 93         }
 94     }
 95 //    cout<<ans<<endl;
 96     mem(vis,0);
 97     for(int i=1;i<=n;++i)SZ[i]=1;
 98     for(int i=1;i<=n;++i)fa[i]=i;
 99     for(int i=n;i>=1;--i)
100     {
101         int now=a[i].second;
102         vis[now]=1;
103         int sz=G[now].size();
104         for(int j=0;j<sz;++j)
105         {
106             int to=G[now][j];
107             if(vis[to])
108             {
109                 ans=(ans-a[i].first*SZ[now]%mod*SZ[Find(to)]%mod+mod)%mod;
110                 SZ[now]+=SZ[Find(to)];
111                 fa[Find(to)]=Find(now);
112             }
113         }
114     }
115     pr("%lld\n",ans);
116 }
117
118 int main()
119 {
120     int T;
121     sc("%d",&T);
122     while(T--)solve();
123     return 0;
124 }
125
126 /**************************************************************************************/
02-09 20:20