SB题目卡我常数
最后寄刀片成功!时限提高到100s
A了!!
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
using namespace std;
#define ll long long
#define youhua __attribute__((optimize("O3")))
char c;
bool flag;
youhua inline void read(int &a)
{
a=0;do c=getchar();while(c!='-'&&(c<'0'||c>'9'));
if(c=='-')c=getchar(),flag=true;
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
if(flag)flag=false,a=-a;
}youhua
inline void read(ll &a)
{
a=0;do c=getchar();while(c!='-'&&(c<'0'||c>'9'));
if(c=='-')c=getchar(),flag=true;
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
if(flag)flag=false,a=-a;
}
int Len2[300001];
int ST2[300001][18];
int In2[300001];
int tot2;
int Block[300001];
youhua inline int L2(int x,int y){return Len2[x]<Len2[y]?x:y;}
youhua inline void Bg2()
{
Len2[0]=1<<29;
int base,i,j;
for(i=1,base=1;i<=17;i++,base<<=1)
for(j=1;j<=tot2;j++)
ST2[j][i]=L2(ST2[j][i-1],ST2[j+base][i-1]);
int con=0;
}
int LC,LC1;
youhua inline int LCA2(int a,int b)
{LC++;
if(!(a^b))return a;
int x=In2[a],y=In2[b];
if(x>y)swap(x,y);
int Len=y-x+1;
int Bl=Block[Len];
return L2(ST2[x][Bl],ST2[y-(1<<Bl)+1][Bl]);
}
int Len[300001];
int ST[300001][18];
int In[300001];
int tot;
youhua inline int L(int x,int y){return Len[x]<Len[y]?x:y;}
youhua inline int LCA(int a,int b)
{LC1++;
if(!(a^b))return a;
int x=In[a],y=In[b];
if(x>y)swap(x,y);
int Len=y-x+1,Bl=Block[Len];
return L(ST[x][Bl],ST[y-(1<<Bl)+1][Bl]);
}
youhua
int Dis(int u,int v){return Len[u]+Len[v]-2*Len[LCA(u,v)];}
youhua
inline void Bg()
{
Len[0]=1ll<<29;
int base;
for(int i=1,base=1;i<=17;i++,base<<=1)
for(int j=1;j<=tot;j++)
ST[j][i]=L(ST[j][i-1],ST[j+base][i-1]);
int con=0;
for(int i=1;i<=tot;i++)
if(i^(i&-i))Block[i]=con-1;
else Block[i]=con++;
}
struct Chain
{
int u;
int len;
Chain *next;
}*Head[200001],*HeadDiv[200001];
Chain P[500001];
int o;youhua
inline Chain *Ne(){return P+o++;}
int Q,i,j,k,l;
ll Val[200001],Sum[200001],G[200001];
int DivF[200001];
int n;
int Heavy[200001];
int size[200001];
bool chn[200001];
ll Con[200001];
int Root;
int Max;
int Que;
youhua ll QueryD(int u,int last,int t)
{
Que++;
if(u==0||t==0)
t++,t--;
ll res=0;
if(DivF[u]!=u)
res+=QueryD(DivF[u],u,t);
if(u^last)
res+=Val[u]-G[last]+(Sum[u]-Sum[last])*Dis(u,t);
else res+=Val[u];
return res;
}
const
ll INF=1ll<<62;
youhua
ll Query(int u)
{
ll tmp=INF;
ll sp,son,S,t=QueryD(u,u,u);
for(Chain *tp=Head[u];tp;tp=tp->next)
if(tp->u!=DivF[u])
{
sp=QueryD(tp->u,tp->u,tp->u);
if(tmp>sp)
tmp=sp,son=tp->u;
}
if(tmp<t)
{
for(Chain *tp=HeadDiv[u];tp;tp=tp->next)
if(LCA2(tp->u,son)==tp->u){S=tp->u;break;}
return Query(S);
}
return t;
}
int Mo;youhua
ll Modify(int u,int Cha,int Old)
{
Mo++;
ll Dj;
if(DivF[u]!=u)
Dj=Modify(DivF[u],Cha,Old);
Sum[u]+=Con[Cha]-Old;
ll Di=Dis(u,Cha);
Val[u]+=Di*(Con[Cha]-Old);
G[u]+=Dj*(Con[Cha]-Old);
return Di;
}
youhua inline void Add(int u,int v,int len){Chain *tp=Ne();tp->len=len;tp->u=v;tp->next=Head[u];Head[u]=tp;}
youhua inline void Link(int u,int v){Chain *tp=Ne();tp->u=v;tp->next=HeadDiv[u];HeadDiv[u]=tp;DivF[v]=u;}
youhua void FindRoot(int u,int f)
{
Heavy[u]=0;
size[u]=1;
for(Chain *tp=Head[u];tp;tp=tp->next)
if(tp->u!=f&&!chn[tp->u])
{
FindRoot(tp->u,u);
size[u]+=size[tp->u];
if(size[tp->u]>Heavy[u])Heavy[u]=size[tp->u];
}
Heavy[u]=max(Heavy[u],Max-size[u]);
if(Heavy[u]<Heavy[Root])Root=u;
}
/*
void Made(int u,int fa,int len)
{
Sum[Root]+=Con[u];
Val[Root]+=Con[u]*len;
for(Chain *tp=Head[u];tp;tp=tp->next)
if(tp->u!=fa&&!chn[tp->u])
Made(tp->u,u,len+tp->len);
}*/
youhua
void Div(int u)
{
chn[u]=true;
// Made(u,u,0);
int Old=Max;
for(Chain *tp=Head[u];tp;tp=tp->next)
if(!chn[tp->u])
{
Max=size[tp->u]>size[u]?Old-size[u]:size[tp->u];
Root=0;
FindRoot(tp->u,u);
Link(u,Root);
Div(Root);
}
}
youhua
void DFS(int u,int fa,int len)
{
ST[In[u]=++tot][0]=u;
Len[u]=len;
for(Chain*tp=Head[u];tp;tp=tp->next)
if(tp->u^fa)
{
DFS(tp->u,u,len+tp->len);
ST[++tot][0]=u;
}
if(u^fa)return ;
Bg();
}
int Maxs;
youhua void DFS2(int u,int fa,int len)
{
ST2[In2[u]=++tot2][0]=u;
Len2[u]=len;
for(Chain*tp=HeadDiv[u];tp;tp=tp->next)
if(tp->u^fa)
{
DFS2(tp->u,u,len+1);
ST2[++tot2][0]=u;
}
if(u^fa)return ;
Bg2();
}
youhua
int main()
{
read(n),read(Q);
for(i=1;i<n;i++)
read(j),read(k),read(l),Add(j,k,l),Add(k,j,l);
DFS(1,1,0);
Root=0;
Heavy[0]=1<<29;
Max=n;
FindRoot(1,1);
int r=Root;
DivF[Root]=Root;
Div(Root);
DFS2(r,r,0);
int Old;
ll Ans;
while(Q--)
{
read(i),read(j);
Old=Con[i];
Con[i]+=j;
Modify(i,i,Old);
Ans=Query(r);
printf("%lld\n",Ans);
}
return 0;
}