zoukankan      html  css  js  c++  java
  • 【集训队作业2018】Simple Tree

    不知道什么情况,卡不过去

    先发一个博客了

    upd:块大小改了一下A了

    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("unroll-loops")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include<cctype>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    char buf[(int)2e7],*vin=buf-1;
    #define getchar() (*++vin)
    int x,ch,flag;
    inline int read(){
        flag=0;
        while(isspace(ch=getchar()));
        if(ch==45)ch=getchar(),flag=1;
        x=ch&15;
        while(isdigit(ch=getchar()))x=x*10+(ch&15);
        return flag?-x:x;
    }
    char bufo[(int)2e7],*vout=bufo-1;
    inline void pc(int x){*++vout=x;}
    inline void put(int x){
        if(x>9)put(x/10);
        pc(x%10+48);
    }
    const int maxn = 100100;
    int n,m,t;
    const int bl = 256;
    const int bl4 = bl*4;
    struct block{
        int tag,ad;
        short cnt[maxn<<2];
        inline block(){tag=maxn<<1,memset(cnt,0,sizeof cnt),ad=0;}
        inline void ins(int x){++cnt[x+tag];}
        inline void del(int x){--cnt[x+tag];}
        inline void init(){for(int i=maxn*4-1;i--;)cnt[i]+=cnt[i+1];}
        inline void add(int x){++cnt[x+tag+1];}
        inline void dec(int x){--cnt[x+tag];}
        inline void alladd(){--tag,++ad;}
        inline void alldec(){++tag,--ad;}
        inline int query(){return cnt[tag+1];}
    }b[maxn/bl+1];
    int a[maxn],c[maxn];
    inline int getbit(int x){return a[x]+b[x/bl].ad;}
    inline int is_begin(int x){return x==1||x%bl==0;}
    inline int is_end(int x){return x==n||x%bl==bl-1;}
    inline int nxt_begin(int x){return x==1?bl:x+bl;}
    inline void add(int l,int r){
        if(l / bl == r / bl){
            for(;l<=r;++l)b[l/bl].add(getbit(l)),++a[l];
            return ;
        }
        int L=std::max(l/bl*bl,1),R=l/bl*bl+bl-1;
           if(R-l >= l-L){
            for(;--l>=L;)b[l/bl].dec(getbit(l)),--a[l];
            b[L/bl].alladd();
        }else
            for(;!is_begin(l);++l)b[l/bl].add(getbit(l)),++a[l];
        l=R+1;
        for(;l+bl4<=r;l+=bl4){
            b[l/bl].alladd();
            b[l/bl+1].alladd();
            b[l/bl+2].alladd();
            b[l/bl+3].alladd();
        }
        for(;l+bl<=r;l+=bl)b[l/bl].alladd();
        L=l,R=std::min(L+bl-1,n);
        if(r-L >= R-r){
            for(;++r<=R;)b[r/bl].dec(getbit(r)),--a[r];
            b[L/bl].alladd();
        }else for(;l<=r;++l)b[l/bl].add(getbit(l)),++a[l];
    }
    inline void dec(int l,int r){
        if(l / bl == r / bl){
            for(;l<=r;++l)b[l/bl].dec(getbit(l)),--a[l];
            return ;
        }
        int L=std::max(l/bl*bl,1),R=l/bl*bl+bl-1;
        if(R-l >= l-L){
            for(;--l>=L;)b[l/bl].add(getbit(l)),++a[l];
            b[L/bl].alldec();
        }else
            for(;!is_begin(l);++l)b[l/bl].dec(getbit(l)),--a[l];
        l=R+1;
        for(;l+bl4<=r;l+=bl4){
            b[l/bl].alldec();
            b[l/bl+1].alldec();
            b[l/bl+2].alldec();
            b[l/bl+3].alldec();
        }
        for(;l+bl<=r;l+=bl)b[l/bl].alldec();
        L=l,R=std::min(L+bl-1,n);
        if(r-L >= R-r){
            for(;++r<=R;)b[r/bl].add(getbit(r)),++a[r];
            b[L/bl].alldec();
        }else for(;l<=r;++l)b[l/bl].dec(getbit(l)),--a[l];
    }
    inline int query(int l,int r){
        int ans=0;
        if(l/bl==r/bl){
            for(;l<=r;++l)ans+=getbit(l)>0;
            return ans;
        }
        int L=std::max(l/bl*bl,1),R=l/bl*bl+bl-1;
        if(R-l >= l-L){
            for(;--l>=L;)ans-=getbit(l)>0;
            ans+=b[L/bl].query();
        }else for(;l <= R;++l)ans+=getbit(l)>0;
        l=R+1;
        for(;l+bl4<=r;l+=bl4){
            ans+=b[l/bl].query();
            ans+=b[l/bl+1].query();
            ans+=b[l/bl+2].query();
            ans+=b[l/bl+3].query();
        }
        for(;l+bl<=r;l+=bl)ans+=b[l/bl].query();
        L=l,R=std::min(L+bl-1,n);
        if(r-L >= R-r){
            for(;++r<=R;)ans-=getbit(r)>0;
            ans+=b[L/bl].query();
        }else for(;l<=r;++l)ans+=getbit(l)>0;
        return ans;
    }
    struct T{
        int to,nxt;
    }way[maxn<<1];
    int h[maxn],num;
    inline void adde(int x,int y){
        way[++num]={y,h[x]},h[x]=num;
        way[++num]={x,h[y]},h[y]=num;
    }
    int size[maxn],dfn[maxn],fa[maxn],dep[maxn],vis[maxn],top[maxn],idx;
    inline void build(){
        for(int i=1;i<=n;++i)a[dfn[i]]=c[i];
        for(int i=1;i<=n;++i)b[i/bl].ins(a[i]);
        for(int i=0;i<=n/bl;++i)b[i].init();
    }
    inline void dfs(int x){
        size[x]=vis[x]=1,dep[x]=dep[fa[x]]+1;
        for(int i=h[x];i;i=way[i].nxt)
            if(!vis[way[i].to])fa[way[i].to]=x,dfs(way[i].to),size[x]+=size[way[i].to];
        vis[x]=0;
    }
    inline void dfs(int x,int top){
        vis[x]=1,dfn[x]=++idx,::top[x]=top;
        int ms=0;
        for(int i=h[x];i;i=way[i].nxt)if(!vis[way[i].to]&&size[way[i].to]>size[ms])ms=way[i].to;
        if(ms)dfs(ms,top);
        for(int i=h[x];i;i=way[i].nxt)if(!vis[way[i].to]&&way[i].to!=ms)dfs(way[i].to,way[i].to);
        vis[x]=0;
    }
    inline void modify(int x,int y,int v){
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]])std::swap(x,y);
            (v==1?add:dec)(dfn[top[x]],dfn[x]),x=fa[top[x]];
        }
        (v==1?add:dec)(std::min(dfn[x],dfn[y]),std::max(dfn[x],dfn[y]));
    }
    inline int Query(int x,int y){
        int ans=0;
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]])std::swap(x,y);
            ans+=query(dfn[top[x]],dfn[x]),x=fa[top[x]];
        }
        ans+=query(std::min(dfn[x],dfn[y]),std::max(dfn[x],dfn[y]));
        return ans;
    }
    inline int Query(int x){return query(dfn[x],dfn[x]+size[x]-1);}
    int main(){
        fread(buf,1,sizeof buf,stdin);
        n=read(),m=read(),t=read()==1;
        for(int i=1;i<n;++i)adde(read(),read());
        for(int i=1;i<=n;++i){
            c[i]=read();
            if(c[i] > 100000)c[i]=100001;
            if(c[i] < -100000)c[i]=-100001;
        }
        dfs(1),dfs(1,1),build();
        for(int i=1,l=0;i<=m;++i){
            int x,y,w,opt;
            opt=read();
            if(opt==1) x=read(),y=read(),w=read(),modify(x^l,y^l,w);
            if(opt==2) x=read(),y=read(),put(l=Query(x^l,y^l)),pc(10);
            if(opt==3) x=read(),put(l=Query(x^l)),pc(10);
            l *= t;
        }
        fwrite(bufo,vout-bufo+1,1,stdout);
    }
  • 相关阅读:
    JS面向(基于)对象编程--构造方法(函数)
    一个超简单的马里奥游戏
    JavaScript基于对象编程
    JavaScript基础之函数与数组
    Learn CSS
    The first day of HTML
    mysql cmd 无法登录
    datagrid 扩展 页脚 合计功能
    this高级应用
    (xxx.55).toFixed(1) 无法正确进位处理
  • 原文地址:https://www.cnblogs.com/skip1978/p/10337672.html
Copyright © 2011-2022 走看看