zoukankan      html  css  js  c++  java
  • 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]='
    ';}
        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;
    }
  • 相关阅读:
    C++预备知识
    C++求最小公倍数
    c++编写函数,递归删除字符串中的子串,求删除次数
    ERROR 1452 : Cannot add or update a child row: a foreign key constraint fails
    django快速搭建blog
    北邮 北理 人大经验
    C、C++、Java语言中异常处理机制浅析
    学习git部署
    各种符号的使用情况说明以及区别
    【转】通过fio工具,测试SATA,SAS,SSD 读写性能
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9191872.html
Copyright © 2011-2022 走看看