zoukankan      html  css  js  c++  java
  • BZOJ 2001 线段树+LCT (TLE)

    同是O(nlog^2n)怎么常数差距就这么大呢,,,

    同是LCT  怎么我的和Po姐姐的常数差距就这么大呢

    我绝对是脑子被驴踢了才写这个垃圾算法

    //By SiriusRen
    #include <bits/stdc++.h>
    using namespace std;
    const int N=1000500;
    int n,m,q,xx,yy,zz,tim[N],cnt;
    int first[N],next[N],v[N],tot;
    int fa[N],maxx[N],ch[N][2],rev[N],Q[N],top,opersize;
    const int LIMIT=100000000;
    char in[LIMIT],*p=in;
    inline int getInt(){
        register int res=0;
        while (*p<'0'||*p>'9')*p++;
        while (*p>='0'&&*p<='9')res=res*10+*p++-'0';
        return res;
    }
    struct Road{
        int from,to,wei;Road(){}
        Road(int z,int t,int e){from=z,to=t,wei=e;};
    }road[N],node[N];
    void add(int x,int y){v[++tot]=y,next[tot]=first[x],first[x]=tot;}
    bool isroot(int q){return ch[fa[q]][0]!=q&&ch[fa[q]][1]!=q;}
    void push_up(int p){
        maxx[p]=p;
        if(node[maxx[ch[p][0]]].wei>node[maxx[p]].wei)maxx[p]=maxx[ch[p][0]];
        if(node[maxx[ch[p][1]]].wei>node[maxx[p]].wei)maxx[p]=maxx[ch[p][1]];
    }
    void push_down(int p){rev[ch[p][0]]^=1,rev[ch[p][1]]^=1,rev[p]=0,swap(ch[p][0],ch[p][1]);}
    void rotate(int p){
        int q=fa[p],y=fa[q],x=(ch[q][1]==p);
        ch[q][x]=ch[p][!x],fa[ch[q][x]]=q;
        ch[p][!x]=q,fa[p]=y;
        if(!isroot(q)){
            if(ch[y][1]==q)ch[y][1]=p;
            if(ch[y][0]==q)ch[y][0]=p;
        }fa[q]=p;push_up(q);
    }
    void splay(int x){
        Q[++top]=x;
        for(int i=x;!isroot(i);i=fa[i])Q[++top]=fa[i];
        while(top){if(rev[Q[top]])push_down(Q[top]);top--;}
        for(int y=fa[x];!isroot(x);rotate(x),y=fa[x])if(!isroot(y)){
            if((ch[y][0]==x)^(ch[fa[y]][0]==y))rotate(x);
            else rotate(y);
        }push_up(x);
    }
    void access(int x){for(int t=0;x;t=x,x=fa[x])splay(x),ch[x][1]=t,push_up(x);}
    void makeroot(int x){access(x),splay(x),rev[x]^=1;}
    bool connected(int x,int y){while(fa[x])x=fa[x];while(fa[y])y=fa[y];return x==y;}
    void link(int x,int y){makeroot(x),fa[x]=y;}
    void split(int x,int y){makeroot(x),access(y),splay(y);}
    void cut(int x,int y){split(x,y),ch[y][0]=fa[x]=0;push_up(y);}
    void insert(int l,int r,int pos,int L,int R,int wei){
        if(l>=L&&r<=R){add(pos,wei);return;}
        int mid=(l+r)>>1,lson=pos<<1,rson=lson|1;
        if(mid<L)insert(mid+1,r,rson,L,R,wei);
        else if(mid>=R)insert(l,mid,lson,L,R,wei);
        else insert(l,mid,lson,L,R,wei),insert(mid+1,r,rson,L,R,wei);
    }
    pair<bool,int>oper[N];
    void dfs(int l,int r,int pos,long long ans){
        int bottom=opersize;
        for(int i=first[pos];i;i=next[i]){
            Road temp=node[v[i]];
            if(temp.from==temp.to)continue;
            if(connected(temp.from,temp.to)){
                split(temp.from,temp.to);
                int tmp=maxx[temp.to];
                if(node[tmp].wei<=temp.wei)continue;
                ans-=node[tmp].wei;
                cut(tmp,node[tmp].from),cut(tmp,node[tmp].to);
                oper[++opersize]=make_pair(0,tmp);
            }
            ans+=temp.wei;
            link(v[i],temp.from),link(v[i],temp.to);
            oper[++opersize]=make_pair(1,v[i]);
        }
        int mid=(l+r)>>1,lson=pos<<1,rson=lson|1;
        if(l==r){if(mid)printf("%lld
    ",ans);}
        else dfs(l,mid,lson,ans),dfs(mid+1,r,rson,ans);
        while(opersize>bottom){
            pair<bool,int>jy=oper[opersize--];
            if(!jy.first)link(jy.second,node[jy.second].from),link(jy.second,node[jy.second].to);
            else cut(jy.second,node[jy.second].from),cut(jy.second,node[jy.second].to);
        }
    }
    int main(){
        fread(p,1,LIMIT,stdin);
        n=getInt(),m=getInt(),q=getInt();
        for(int i=1;i<=m;i++)xx=getInt(),yy=getInt(),zz=getInt(),road[i]=Road(xx,yy,zz);
        for(int i=0;i<=n;i++)node[i].wei=-1;
        for(int i=1;i<=q;i++){
            xx=getInt(),zz=getInt(),
            node[++cnt+n]=road[xx];
            insert(0,q,1,tim[xx],i-1,cnt+n);
            tim[xx]=i,road[xx].wei=zz;
        }
        for(int i=1;i<=m;i++)node[++cnt+n]=road[i],insert(0,q,1,tim[i],q,cnt+n);
        dfs(0,q,1,0);
    }

    就当我理论AC了吧,,, 

  • 相关阅读:
    C# Arrays
    C# 类 (12)
    C# 类 (11)
    C# 类 (10)
    常用的HDFS操作
    Java StringTokenizer 类使用方法
    常用HBase操作
    常用Linux命令
    彻底关闭Windows10的更新
    如何将百度坐标转换为国家2000(或WGS84)坐标系?
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/7087666.html
Copyright © 2011-2022 走看看