异象石(就是sdio宝藏那题)

题解:

之前这道题写过两次题解了吧。。

实现的时候可以用set<int,cmp>来实现按照dfn排序

代码:

感觉别人的分类讨论比我的简单。。

但我觉得我这个写起来也不烦就不看别人的了。。

看了一下 发现他们是把一个的前驱后继处理为自己 于是就避免了分类讨论(我xxx) 

linux复制出来行间距变成两倍了。。

#include <bits/stdc++.h>

using namespace std;

#define rll ll

#define IL inline

#define rep(i,h,t) for (rll i=h;i<=t;i++)

#define dep(i,t,h) for (rll i=t;i>=h;i--) 

#define ll long long 

const ll N=4e5; 

struct re{

    ll a,b,c; 

}e[N*2];

ll cnt,head[N],l;

ll bz[20][N];

ll sum[N]; 

void arr(ll x,ll y,ll z)

{

    e[++l].a=head[x];

    e[l].b=y;

    e[l].c=z;

    head[x]=l; 

} 

ll dfn[N],dep[N]; 

void dfs(ll x,ll y)

{

  dfn[x]=++cnt; dep[x]=dep[y]+1; bz[0][x]=y; 

  for (rll u=head[x];u;u=e[u].a)

  {

      rll v=e[u].b;

    if (v!=y)

    { 

      sum[v]=sum[x]+e[u].c; 

      dfs(v,x); 

    } 

  } 

}

ll lca(ll x,ll y)

{

    if (dep[x]<dep[y]) swap(x,y);

    dep(i,19,0) if (dep[bz[i][x]]>=dep[y]) x=bz[i][x];

    if (x==y) return x;

    dep(i,19,0) if (bz[i][x]!=bz[i][y]) x=bz[i][x],y=bz[i][y];

    return bz[0][x]; 

} 

struct cmp{

    bool operator () (ll x,ll y)

    {

        return dfn[x]<dfn[y];

    }

};

#define tp set<ll,cmp>::iterator

set<ll,cmp> S;

tp it,it2,it3;

IL tp pre(tp it)

{

    tp it2=it; it2--; return(it2);

}

IL tp nxt(tp it)

{

    tp it2=it; it2++; return(it2);

}

int main()

{

    freopen("1.in","r",stdin);

    freopen("1.out","w",stdout);

    ios::sync_with_stdio(false);

    ll n; 

    cin>>n;

    rep(i,1,n-1)

    {

        ll x,y,z;

        cin>>x>>y>>z;

        arr(x,y,z); arr(y,x,z); 

    }

    dfs(1,0);

    rep(i,1,19)

      rep(j,1,n)

        bz[i][j]=bz[i-1][bz[i-1][j]]; 

    ll m;

    cin>>m;

    ll ans=0;

    ll num=0;

    rep(i,1,m)

    {

        char cc; ll x;

        cin>>cc;

        if (cc=='+')

        {

            cin>>x; num++;

            ans+=2*sum[x];

            it =S.insert(x).first;

            if (num==1) continue;

            bool tt=0;

            if (it==S.begin())

            {

                tt=1;

                it2=nxt(it);

                it3=S.end(); it3--;

                if (num!=2)

                                { 

                  ans+=2*sum[lca(*it2,*it3)];

                  ans-=2*sum[lca(x,*it2)];

                  ans-=2*sum[lca(x,*it3)];

                } else ans-=4*sum[lca(x,*it2)];

            }

            it2=nxt(it);

            if (!tt&&it2==S.end())

            {

                tt=1;

                it2=pre(it);

                it3=S.begin();

                if (num!=2)

        { 

                  ans+=2*sum[lca(*it2,*it3)];

                  ans-=2*sum[lca(x,*it2)];

                  ans-=2*sum[lca(x,*it3)];

                } else ans-=4*sum[lca(x,*it2)];

            }

            if (!tt)

            {

                it2=pre(it);

                it3=nxt(it);

                ans+=2*sum[lca(*it2,*it3)];

                ans-=2*sum[lca(x,*it2)];

                ans-=2*sum[lca(x,*it3)];

            }

        }

        if (cc=='-')

        {

            cin>>x; num--;

            if (!num)

            {

                ans=0; S.clear(); 

                continue;

            }

            it=S.find(x);

            ans-=2*sum[x];

            bool tt=0;

            if (it==S.begin())

            {

                tt=1;

                it2=nxt(it);

                it3=S.end(); it3--;

                if (num>=2)

                {

                  ans-=2*sum[lca(*it2,*it3)];

                  ans+=2*sum[lca(x,*it2)];

                  ans+=2*sum[lca(x,*it3)];

                } else ans+=4*sum[lca(x,*it3)];

            }

            it2=nxt(it);

            if (!tt&&it2==S.end())

            {

                tt=1;

                it2=pre(it);

                it3=S.begin();

                if (num>=2)

                {

                  ans-=2*sum[lca(*it2,*it3)];

                  ans+=2*sum[lca(x,*it2)];

                  ans+=2*sum[lca(x,*it3)];

                } else ans+=4*sum[lca(x,*it3)];

            }

            if (!tt)

            {

                it2=pre(it);

                it3=nxt(it);

                ans-=2*sum[lca(*it2,*it3)];

                ans+=2*sum[lca(x,*it2)];

                ans+=2*sum[lca(x,*it3)];

            }

            S.erase(x);

        }

        if (cc=='?')

        {

            if (num<=1) cout<<0<<endl;

            else cout<<ans/2<<endl;

        }

    }

    return 0; 

} 

 

posted @ 2018-10-29 19:34  尹吴潇  阅读(263)  评论(0编辑  收藏  举报