• BZOJ 3083 树链剖分+倍增+线段树


    思路:
    先随便选个点 链剖+线段树
    1操作 就直接改root变量的值
    2操作 线段树上改
    3操作
    分成三种情况
    1.new root = xx 整个子树的min就是ans
    2. lca(new root,xx) !=xx query 一下 当前的标号 和当前的标号+size(链剖不就是个特殊的dfs序嘛)
    3. lca(new root,xx) =xx 找一下root在xx的哪个子树里 这个子树的补集就是解了

    好多题解写得是有问题的
    他们找root在xx的哪个子树里 这个操作是暴力找的 会被菊花图卡
    (所以我就又写了个倍增)

    后附 对拍程序 (这玩意儿一遍AC真是幻想 啊……)

    //By SiriusRen33333333333333
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 222222
    int n,m,op,xx,yy,zz,v[N],next[N],first[N],tot,wei[N],tree[N*8],lazy[N*8];
    int size[N],son[N],fa[N],deep[N],top[N],change[N],cnt,root,f[N][20],rev[N];
    void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;}
    void dfs(int x){
        size[x]=1;
        for(int i=1;i<=19;i++)if((1<<i)<=deep[x])f[x][i]=f[f[x][i-1]][i-1];else break;
        for(int i=first[x];~i;i=next[i])if(v[i]!=fa[x]){
            fa[v[i]]=f[v[i]][0]=x,deep[v[i]]=deep[x]+1,dfs(v[i]);
            size[x]+=size[v[i]];
            if(size[son[x]]<size[v[i]])son[x]=v[i];
        }
    }
    void dfs2(int x,int tp){
        change[x]=++cnt,rev[cnt]=x,top[x]=tp;
        if(son[x])dfs2(son[x],tp);
        for(int i=first[x];~i;i=next[i])
            if(v[i]!=fa[x]&&v[i]!=son[x])
                dfs2(v[i],v[i]);
    }
    void push_down(int pos){lazy[pos<<1]=lazy[pos<<1|1]=tree[pos<<1]=tree[pos<<1|1]=lazy[pos];lazy[pos]=-1;}
    void build(int l,int r,int pos){
        if(l==r){tree[pos]=wei[rev[l]];return;}
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        build(l,mid,lson),build(mid+1,r,rson);
        tree[pos]=min(tree[lson],tree[rson]);
    }
    void insert(int l,int r,int pos,int L,int R,int val){
        if(l>=L&&r<=R){tree[pos]=lazy[pos]=val;return;}
        if(~lazy[pos])push_down(pos);
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid<L)insert(mid+1,r,rson,L,R,val);
        else if(mid>=R)insert(l,mid,lson,L,R,val);
        else insert(l,mid,lson,L,R,val),insert(mid+1,r,rson,L,R,val);
        tree[pos]=min(tree[lson],tree[rson]);
    }
    int query(int l,int r,int pos,int L,int R){
        if(l>=L&&r<=R)return tree[pos];
        if(~lazy[pos])push_down(pos);
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid<L)return query(mid+1,r,rson,L,R);
        else if(mid>=R)return query(l,mid,lson,L,R);
        else return min(query(l,mid,lson,L,R),query(mid+1,r,rson,L,R));
    }
    void Change(int x,int y,int val){
        int fx=top[x],fy=top[y];
        while(fx!=fy){
            if(deep[fx]<deep[fy])swap(x,y),swap(fx,fy);
            insert(1,n,1,change[fx],change[x],val);
            x=fa[fx],fx=top[x];
        }if(deep[x]>deep[y])swap(x,y);
        insert(1,n,1,change[x],change[y],val);
    }
    int LCA(int x,int y){
        int fx=top[x],fy=top[y];
        while(fx!=fy){
            if(deep[fx]<deep[fy])swap(x,y),swap(fx,fy);
            x=fa[fx],fx=top[x];
        }return deep[x]>deep[y]?y:x;
    }
    int main(){
        memset(first,-1,sizeof(first)),memset(lazy,-1,sizeof(lazy));
        scanf("%d%d",&n,&m);
        for(int i=1;i<n;i++)scanf("%d%d",&xx,&yy),add(xx,yy),add(yy,xx);
        for(int i=1;i<=n;i++)scanf("%d",&wei[i]);
        dfs(1),dfs2(1,1),build(1,n,1);
        scanf("%d",&root);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&op,&xx);
            if(op==1)root=xx;
            else if(op==2)scanf("%d%d",&yy,&zz),Change(xx,yy,zz);
            else{
                if(root==xx){printf("%d
    ",tree[1]);continue;}
                int lca=LCA(xx,root);
                if(xx!=lca)printf("%d
    ",query(1,n,1,change[xx],change[xx]+size[xx]-1));
                else{
                    int tmp=deep[root]-deep[xx]-1,ans=0x3f3f3f3f;yy=root;
                    for(int i=0;i<=19;i++)if((1<<i)&tmp)yy=f[yy][i];
                    if(change[yy]>1)ans=query(1,n,1,1,change[yy]-1);
                    if(change[yy]+size[yy]<=n)ans=min(ans,query(1,n,1,change[yy]+size[yy],n));
                    printf("%d
    ",ans);
                }
            }
        }
    }

    maker

    //By SiriusRen
    #include <ctime>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int n=100000,m=100000,seed;
    int main(){
        freopen("seed.txt","r",stdin);
        scanf("%d",&seed);
        srand(seed+time(0));rand();rand();rand();rand();rand();rand();rand();rand();
        freopen("seed.txt","w",stdout);
        printf("%d
    ",seed);
        freopen("in.txt","w",stdout);
        printf("%d %d
    ",n,m);
        for(int i=2;i<=n;i++)printf("%d %d
    ",rand()%(i-1)+1,i);
        for(int i=1;i<=n;i++)printf("%d ",rand()+1);
        printf("
    %d
    ",rand()%n+1);
        for(int i=1;i<=m;i++){
            int temp=rand();
            if(temp%3==0)printf("1 %d
    ",rand()%n+1);
            else if(temp%3==1)printf("2 %d %d %d
    ",rand()%n+1,rand()%n+1,rand()+1);
            else printf("3 %d
    ",rand()%n+1);
        }
    }
    

    对拍:

    //By SiriusRen
    #include <ctime>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int cases;
    int main(){
        while(1){
            printf("Case %d now~~~
    ",++cases);
            system("mk.exe");
            int lasttime=clock();
            system("mine.exe<in.txt>out1.txt");
            printf("mine  time=%ld
    ",clock()-lasttime);
            lasttime=clock();
            system("sol.exe<in.txt>out2.txt");
            printf("solution  time=%ld
    ",clock()-lasttime);
            lasttime=clock();
            if(system("fc out1.txt out2.txt")){
                puts("Wrong Answer~~~");
                while(1);
            }
        }
    }
    

    这里写图片描述

  • 相关阅读:
    VSCode插件开发全攻略(一)概览
    如何使用JavaScript实现纯前端读取和导出excel文件
    ReactNative学习笔记(七)Navigator的使用
    ReactNative学习笔记(六)集成视频播放
    ReactNative学习笔记(五)踩坑总结
    ReactNative学习笔记(四)热更新和增量更新
    ReactNative学习笔记(三)打包、调试、运行等相关介绍
    ReactNative学习笔记(二)基础进阶
    ReactNative学习笔记(一)环境搭建
    彻底禁用Chrome的“请停用以开发者模式运行的扩展程序”提示
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532107.html
Copyright © 2020-2023  润新知