An unknown god Ben a set of Noip simulation questions T3.
The rest is fine, and the question is how to find the path between any two points on a path.
First, it is easy to think of the most violent enumeration two points of distance into the enumeration edge and then use the multiplication principle to calculate the contribution of each edge to the answer, a computational complexity of $o (N) $. It is obvious to optimize on top of that.
How do I turn each enumeration into a prefix and a calculation? This is a question to think about, but simple prefixes and obviously not feasible. Because the front coefficients of each edge vary depending on how many points to the left and right of each edge. This can be done by introducing a depth in the prefix and. The first factor can be done with some processing. But there is also a factor before each coefficient. So in the prefix and in the introduction of the depth of the square, and then after some magical processing will be able to get the answer!
Ecstasy//by cydiater//2016.10.24#include <iostream> #include <cstdlib> #include <cstdio> #include <queue> #include <map> #include <ctime> #include <cmath> #include <iomanip> #include < cstring> #include <string> #include <algorithm> #include <bitset>using namespace std; #define LL Long long#define Up (i,j,n) for (int. i=j;i<=n;i++) #define DOWN (i,j,n) for (int i=j;i>=n;i--) #define FILE "Ecstasy" CONST LL Maxn=1e5+5;const ll Oo=1ll<<60;inline ll read () {char ch=getchar (); ll X=0,f=1;while (ch> ' 9 ' | | ch< ' 0 ') {if (ch== '-') F=-1;ch=getchar ();} while (ch>= ' 0 ' &&ch<= ' 9 ') {x=x*10+ch-' 0 '; Ch=getchar ();} return x*f;} ll n,m,fa[maxn][30],f[maxn],dep[maxn],dis[maxn],ndis[maxn],n2dis[maxn],link[maxn],len=0;struct edge{ll y,next,v;} E[maxn<<1];struct ask{ll Opt,x,y,v,ans;} Ask[maxn<<3];namespace solution{inline void Insert (ll x,ll Y,ll v) {e[++len].next=link[x]; Link[x]=len;e[len].y=y;e[len].v=v;} int getf (int k) {if (f[k]==k) return K;F[K]=GETF (F[k]); return f[k];} void Dfs (int node,int deep,int father) {fa[node][0]=father;dep[node]=deep;for (int i=link[node];i;i=e[i].next) if (E[i] . Y!=father) {dis[e[i].y]=dis[node]+e[i].v;ndis[e[i].y]=ndis[node]+ (N-dep[node]) *e[i].v;n2dis[e[i].y]=n2dis[node ]+ (N-dep[node]) * (N-dep[node]) *e[i].v;dfs (E[i].y,deep+1,node);}} void Get_ancstor () {Up (i,1,20) up (node,1,n) if (fa[node][i-1]!=0) fa[node][i]=fa[fa[node][i-1]][i-1];} void Init () {n=read (); M=read (); Up (I,1,n) f[i]=i;up (i,1,m) {ll opt=read (), X=read (), Y=read (), v;if (opt==1) {v=read (); f[getf (x)]=getf (y); Insert (x,y,v); insert (Y,X,V);} else if (GETF (x)!=getf (y)) ask[i].ans=-1;ask[i].opt=opt;ask[i].x=x;ask[i].y=y;ask[i].v=v;} DFS (1,0,0); Get_ancstor ();} int LCA (int x,int y) {if (x==y) return x;if (Dep[x]<dep[y]) swap (x, y);d Own (i,20,0) if (dep[x]-(1<<i) >=dep[y]) X=fa[x][i];if (x==y) return X;down (i,20,0) if (Fa[x][i]!=0&&fa[x][i]!=fa[y][i]) {x=fa[x][i];y=fa[y][i];} return fa[x][0];} ll get (ll x,ll y) {int Lca=lca (x, y); ll num=dep[x]+dep[y]-(Dep[lca]<<1), ll ixsum=ndis[x]-ndis[lca]-(Dis[x]-dis[lca]) * (N-dep[x]); ll iysum=ndis[y]-ndis[lca]-(Dis[y]-dis[lca]) * (N-dep[y]); ll i2xsum=n2dis[x]-n2dis[lca]-(Dis[x]-dis[lca]) * (N-dep[x]) * (N-dep[x])-(n-dep[x]) * (ixsum<<1); ll i2ysum=n2dis[y]-n2dis[lca]-(Dis[y]-dis[lca]) * (N-dep[y]) * (N-dep[y])-(N-dep[y]) * (iysum<<1); return (num+1) * ( ixsum+iysum)-i2xsum-i2ysum;} void Slove () {Up (i,1,m) if (ask[i].opt==2&&ask[i].ans!=-1) ask[i].ans=get (ASK[I].X,ASK[I].Y);} void output () {Up (i,1,m) if (ask[i].opt==2) printf ("%i64d\n", Ask[i].ans);}} int main () {freopen (file ".", "R", stdin), freopen (file ". Out", "w", stdout); using namespace Solution;init (); Slove (); O Utput (); return 0;}
Special Education's rational pleasure