3159: 决战

题解:

这个有利用比较好的理解lct。。

但是呀这里你思路理清楚了也不好写。。

细节挺多的

关键是非常难调。。。

代码:

#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for (int i=h;i<=t;i++)
#define dep(i,t,h) for (int i=t;i>=h;i--)
#define me(x) memset(x,0,sizeof(x))
#define ll long long
#define mep(x) memcpy(x,y,sizeof(y))
#define mid ((h+t)>>1)
namespace IO{
    char ss[1<<24],*A=ss,*B=ss;
    IL char gc()
    {
        return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;
    }
    template<class T>void read(T &x)
    {
        rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
        while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f;
    }
    IL void read2(string &x)
    {
        rint f=1,c; while (c=gc(),!(('A'<=c&&c<='Z')||('a'<=c&&c<='z'))); x=c;  
        while (c=gc(),(('A'<=c&&c<='Z')||('a'<=c&&c<='z'))) {char c1=c; x+=c1; }
    }
    char sr[1<<24],z[20]; int Z,C=-1;
    template<class T>void wer(T x)
    {
        if (x<0) sr[++C]='-',x=-x;
        while (z[++Z]=x%10+48,x/=10);
        while (sr[++C]=z[Z],--Z);
    }
    IL void wer1() {sr[++C]=' ';}
    IL void wer2() {sr[++C]='\n';}
    template<class T>IL void maxa(T &x,T y) { if (x<y) x=y;}
    template<class T>IL void mina(T &x,T y) { if (x>y) x=y;}
    template<class T>IL T MAX(T x,T y) {return x>y?x:y;}
    template<class T>IL T MIN(T x,T y) {return x<y?x:y;}
};
using namespace IO;
const int N=6e4;
const int INF=1e9;
struct re{
    ll a,b,c;
}e[N*2];
int l,head[N];
IL void arr(int x,int y)
{
    e[++l].a=head[x];
    e[l].b=y;
    head[x]=l;
}
struct Splay{
    bool rev[N];
    int ls[N],rs[N],fa[N],num[N],ma[N],v[N],na[N],dy[N],lazy[N];
    ll sum[N];
    Splay() {rep(i,0,N-1) num[i]=0; na[0]=INF;} 
    IL void down(int x)
    {
        if (ls[x])
        {
            if (rev[x])
            {
                swap(ls[ls[x]],rs[ls[x]]);
                rev[ls[x]]^=1;
            }
            if (lazy[x])
            {
                lazy[ls[x]]+=lazy[x];
                v[ls[x]]+=lazy[x];
                sum[ls[x]]+=1ll*num[ls[x]]*lazy[x];
                ma[ls[x]]+=lazy[x]; na[ls[x]]+=lazy[x];
            }
        }
        if (rs[x])
        {
          if (rev[x])
          {
              swap(ls[rs[x]],rs[rs[x]]);
              rev[rs[x]]^=1;
          }
          if (lazy[x])
          {
              lazy[rs[x]]+=lazy[x];
              v[rs[x]]+=lazy[x];
              sum[rs[x]]+=1ll*num[rs[x]]*lazy[x];
              ma[rs[x]]+=lazy[x]; na[rs[x]]+=lazy[x];
          }
        }
        rev[x]=lazy[x]=0; 
    }
    IL void updata(int x)
    {
        sum[x]=v[x]+sum[ls[x]]+sum[rs[x]];
        ma[x]=MAX(v[x],MAX(ma[ls[x]],ma[rs[x]]));
        na[x]=MIN(v[x],MIN(na[ls[x]],na[rs[x]]));
        num[x]=num[ls[x]]+num[rs[x]]+1;
    }
    IL void push_rev(int x)
    {
        rev[x]^=1;
        swap(ls[x],rs[x]);
    }
    IL bool pd(int x)
    {
        return ls[fa[x]]==x||rs[fa[x]]==x;
    }
    void rotate(int x,int y)
    {
        int f1=fa[x];
        if (y==1)
        { 
          rs[f1]=ls[x];
          if (rs[f1]) fa[rs[f1]]=f1;
        } else
        {
          ls[f1]=rs[x];
          if (ls[f1]) fa[ls[f1]]=f1;
        }
        fa[x]=fa[f1];
        if (pd(f1))
        {
            if (ls[fa[f1]]==f1) ls[fa[x]]=x;
            else rs[fa[x]]=x;
        }
        fa[f1]=x;
        if (y==1) ls[x]=f1; else rs[x]=f1;
        updata(f1); updata(x);
    }
    int dfs(int x)
    {
        int ans=x;
        if (pd(x)) ans=dfs(fa[x]);
        down(x);
        return ans;
    }
    void splay(int x)
    {
        int k=dfs(x); dy[x]=dy[k];
        int f1=fa[x];
        while (pd(x))
        {
            if (!pd(fa[x]))
              if (ls[f1]==x) rotate(x,2); else rotate(x,1);
            else 
            if (ls[fa[f1]]==f1)
              if (ls[f1]==x)
                rotate(f1,2),rotate(x,2);
              else rotate(x,1),rotate(x,2);
            else 
              if (rs[f1]==x)
                rotate(f1,1),rotate(x,1);
              else rotate(x,2),rotate(x,1);
            f1=fa[x];
        }
    }
    int find(int x,int k)
    {
        splay(x);
        while (1)
        {
            down(x);
            if (num[ls[x]]+1==k) return(x);
            if (num[ls[x]]+1<k) k-=num[ls[x]]+1,x=rs[x];
            else x=ls[x];
        }
    }
}S1,S2;
struct lct{
    IL int pos(int x)
    {
        return S2.find(S1.dy[x],S1.num[S1.ls[x]]+1); 
    }
    void access(int x)
    {
        int x2;
        for (int y1=0,y2=0;x;x=S1.fa[x])
        {
            S1.splay(x);  
            x2=pos(x); 
            S2.splay(x2);
            if (S1.rs[x]) S1.dy[S1.rs[x]]=S2.rs[x2];
            S1.dy[x]=x2;
            S1.rs[x]=y1; S2.rs[x2]=y2; 
            if (y2) S2.fa[y2]=x2;
            S1.updata(x); S2.updata(x2);
            y1=x; y2=x2; 
        }
    }
    IL int gao2(int x)
    {
        access(x);
        S1.splay(x); 
        int x2=pos(x);
        S2.splay(x2);
        return x2;
    }
    void mkr(int x)
    {
        int x2=gao2(x);
        S1.push_rev(x); S2.push_rev(x2);
    }
    void split(int x,int y)
    {
        mkr(x); 
        gao2(y);
    }
    re query(int x,int y)
    {
        S1.splay(y);
        int k=pos(y);
        split(x,y);
        return (re){S2.sum[k],S2.ma[k],S2.na[k]};
    }
    void change(int x,int y,int z)
    {
        S1.splay(y);
        int k=pos(y);
        split(x,y);
        S2.sum[k]+=1ll*z*S2.num[k]; S2.v[k]+=z;
        S2.ma[k]+=z; S2.na[k]+=z;
        S2.lazy[k]+=z; 
    }
    void reverse(int x,int y)
    {
        S1.splay(y);
        int k=pos(y);
        split(x,y); 
        S2.push_rev(k);
    }
}L;
void dfs(int x,int y)
{
    S1.fa[x]=y; S2.fa[x]=y;
    S1.dy[x]=x;
    for(rint u=head[x];u;u=e[u].a)
    {
        int v=e[u].b;
        if (v!=y) dfs(v,x);
    }
}
int main()
{
    freopen("1.in","r",stdin);
    freopen("1.out","w",stdout);
    int n,m,Q;
    read(n); read(m); read(Q);
    rep(i,1,n-1)
    {
        int x,y;
        read(x); read(y); arr(x,y); arr(y,x);
    }
    dfs(Q,0);
    rep(i,1,m)
    {
        int x,y,z;
        string s;
        read2(s); ll ans;
        if(s[0]=='I'&&s[2]=='c')
        {
            read(x); read(y); read(z);
            L.change(x,y,z);
        } else
        {
             read(x); read(y);
             if (s[0]=='S')
             {
                ans=L.query(x,y).a;
                wer(ans); wer2();
             }
             if (s[1]=='a')
             {
                 ans=L.query(x,y).b;
                 wer(ans); wer2();
             }
             if (s[1]=='i')
             {
                 ans=L.query(x,y).c;
                 wer(ans); wer2();
             }
             if (s[0]=='I')
             {
                 L.reverse(x,y);
             }
        }
    }
    fwrite(sr,1,C+1,stdout);
    return 0;
}

 

posted @ 2018-12-21 11:20  尹吴潇  阅读(180)  评论(0编辑  收藏  举报