BZOJ3924: [Zjoi2015]幻想乡战略游戏

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;
}

你可能感兴趣的:(BZOJ3924: [Zjoi2015]幻想乡战略游戏)