• CodeChef June Challenge 2017


    好气啊,本来以为比赛时间还有很多,结果回家养病两天回到学校怎么比赛就结束了(雾),大约是小高考弄错了时间?

    挑3道有意思的写写题解吧。

    Cloning

    题目大意:给一个序列,每次询问两个等长区间,问区间内的数是否排序后至多只有一个对应位不同。

    题解:主席树维护一下hash,求出最大的k,使得两个区间中的前k大在排序后相同,然后判一下后缀即可。

    #include<cstdio>
    #include<algorithm>
    #define MN 110000
    #define ull unsigned long long
    using namespace std;
    
    int read_p,read_ca;
    inline int read(){
        read_p=0;read_ca=getchar();
        while(read_ca<'0'||read_ca>'9') read_ca=getchar();
        while(read_ca>='0'&&read_ca<='9') read_p=read_p*10+read_ca-48,read_ca=getchar();
        return read_p;
    }
    const ull base=2636363;
    int T,n,m,ro[MN],num=0,a,b,c,d;
    ull H[MN];
    struct na{int l,r,s;ull h;na(){s=h=0;}}t[MN*20];
    inline void add(int &p,int x,int l,int r,int k){
        p=++num;t[p]=t[x];
        t[p].h+=H[k];t[p].s++;
        if (l==r) return;
        int mid=l+r>>1;
        if (k<=mid) add(t[p].l,t[x].l,l,mid,k);else add(t[p].r,t[x].r,mid+1,r,k);
    }
    inline int aski(int a,int b,int c,int d,int l,int r){
        if (t[b].h-t[a].h==t[d].h-t[c].h&&t[b].s-t[a].s==t[d].s-t[c].s) return t[b].s-t[a].s;
        if (l==r) return min(t[b].s-t[a].s,t[d].s-t[c].s);
        int mid=l+r>>1;
        int mmh=aski(t[a].l,t[b].l,t[c].l,t[d].l,l,mid);
        if (mmh==t[t[b].l].s-t[t[a].l].s&&mmh==t[t[d].l].s-t[t[c].l].s) mmh+=aski(t[a].r,t[b].r,t[c].r,t[d].r,mid+1,r);
        return mmh;
    }
    inline int aska(int a,int b,int c,int d,int l,int r){
        if (t[b].h-t[a].h==t[d].h-t[c].h&&t[b].s-t[a].s==t[d].s-t[c].s) return t[b].s-t[a].s;
        if (l==r) return min(t[b].s-t[a].s,t[d].s-t[c].s);
        int mid=l+r>>1;
        int mmh=aska(t[a].r,t[b].r,t[c].r,t[d].r,mid+1,r);
        if (mmh==t[t[b].r].s-t[t[a].r].s&&mmh==t[t[d].r].s-t[t[c].r].s) mmh+=aska(t[a].l,t[b].l,t[c].l,t[d].l,l,mid);
        return mmh;
    }
    int main(){
        int i;
        T=read();
        H[1]=1;
        for (i=2;i<=1e5;i++) H[i]=H[i-1]*base;
        while(T--){
            n=read();m=read();num=0;
            for (i=1;i<=n;i++) add(ro[i],ro[i-1],1,1e5,read());
            while(m--){
                a=read();b=read();c=read();d=read();
                puts(aska(ro[a-1],ro[b],ro[c-1],ro[d],1,1e5)+aski(ro[a-1],ro[b],ro[c-1],ro[d],1,1e5)>=b-a?"YES":"NO");
            }
        }
    } 
    View Code

    Euler Sum

    题目大意:求$sum_{1}^{n}leftlfloor i*e ight floor$

    题解:连分数求出e的近似分数以后类欧即可

    z,m=1,0
     
    def work(x):
        global z,m
        z,m=m,z
        z+=m*x
    def mmh(n,z,m):
        if n==0 or z==0 or m==0:
            return 0
        p=int(z//m)
        z-=int(p*m)
        N=int(n*z//m)
        return n*(n+1)//2*p+int(n*N)-int(mmh(N,m,z))
     
    i=3000
    while (i>0):
        work(i*2)
        work(1)
        work(1)
        i-=1
    z+=m
    n=int(input())
    mmh=0
    f=1
    while(n>0):
        p=z//m
        z-=p*m
        N=n*z//m
        mmh+=f*(n*(n+1)//2*p+n*N)
        f*=-1
        n=N
        z,m=m,z
    print(mmh) 
    View Code

    Persistent oak

    题意:不想写啊

    题解:链剖后可持久化线段树即可,注意打标记,下放标记的时候都要新建节点,不然会影响到历史版本。

    #include<cassert>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define MN 210000
    #define lp t[p].l
    #define rp t[p].r
    using namespace std;
    
    int read_p,read_ca;
    inline int read(){
        read_p=0;read_ca=getchar();
        while(read_ca<'0'||read_ca>'9') read_ca=getchar();
        while(read_ca>='0'&&read_ca<='9') read_p=read_p*10+read_ca-48,read_ca=getchar();
        return read_p;
    }
    struct na{int y,ne;}b[MN<<1];
    struct tree{int l,r,M,m,d;bool re;}t[MN*200];
    int T,n,m,ty,l[MN],fa[MN],si[MN],de[MN],son[MN],to[MN],x,y,w[MN],df[MN],pdf[MN],lo[MN],ro[MN],nm,NUM,num;
    char s[10];
    inline void in(int x,int y){b[++num].y=y;b[num].ne=l[x];l[x]=num;}
    inline int min(int a,int b){return a<b?a:b;}
    void dfs(int x){
        si[x]=1;son[x]=0;
        for (int i=l[x];i;i=b[i].ne)
        if (fa[b[i].y]=x,de[b[i].y]=de[x]+1,dfs(b[i].y),si[x]+=si[b[i].y],si[son[x]]<si[b[i].y]) son[x]=b[i].y;
    }
    void DFS(int x,int p){
        to[x]=p;df[x]=++nm;pdf[nm]=x;
        if (son[x]) DFS(son[x],p);
        for (int i=l[x];i;i=b[i].ne)
        if (b[i].y!=son[x]) DFS(b[i].y,b[i].y);
        lo[x]=nm;
    }
    inline void hb(int &p,int d,bool bo=0){
        if (!p) return;
        t[++NUM]=t[p];p=NUM;
        if (bo) t[p].re=1,t[p].m=t[p].M,t[p].d=0;else t[p].m+=d,t[p].d+=d,assert(t[p].m<=t[p].M);
    }
    inline void pd(int &p){
        t[++NUM]=t[p];p=NUM;
        if (t[p].re) hb(lp,0,1),hb(rp,0,1),t[p].re=0;
        if (t[p].d) hb(lp,t[p].d),hb(rp,t[p].d),t[p].d=0;
    }
    inline void gx(int &p){
        t[p].m=min(t[lp].m,t[rp].m);
        t[p].M=min(t[lp].M,t[rp].M);
    }
    void build(int &p,int l,int r){
        p=++NUM;t[p].l=t[p].r=t[p].d=t[p].re=0;
        if (l==r){
            t[p].M=t[p].m=w[pdf[l]];
            return;
        }
        int mid=l+r>>1;
        build(t[p].l,l,mid);build(t[p].r,mid+1,r);
        gx(p);
    }
    void add(int &p,int x,int l,int r,int L,int R,int d){
        p=++NUM;t[p]=t[x];
        pd(p);x=p;
        if (L==l&&R==r) hb(p,d);else{
            int mid=l+r>>1;
            if (R<=mid) add(lp,t[x].l,l,mid,L,R,d);else
            if (L>mid) add(rp,t[x].r,mid+1,r,L,R,d);else
            add(lp,t[x].l,l,mid,L,mid,d),add(rp,t[x].r,mid+1,r,mid+1,R,d);
            gx(p);
        }
    }
    int ask(int &p,int l,int r,int k){
        pd(p);
        if (l==r) return t[p].m;
        int mid=l+r>>1;
        if (k<=mid) return ask(lp,l,mid,k);else return ask(rp,mid+1,r,k);
    }
    int mask(int &p,int l,int r,int L,int R){
        pd(p);
        if (t[p].m>=0) return -1;
        if (l==r) return pdf[l];
        int mid=l+r>>1,s;
        if (R<=mid) return mask(lp,l,mid,L,R);else
        if (L>mid) return mask(rp,mid+1,r,L,R);else
        if (s=mask(rp,mid+1,r,mid+1,R),s!=-1) return s;else return mask(lp,l,mid,L,mid);
    }
    inline void reset(int &p,int x,int l,int r,int L,int R){
        p=++NUM;t[p]=t[x];
        pd(p);x=p;
        if (L==l&&R==r) hb(p,0,1);else{
            int mid=l+r>>1;
            if (R<=mid) reset(lp,t[x].l,l,mid,L,R);else
            if (L>mid) reset(rp,t[x].r,mid+1,r,L,R);else
            reset(lp,t[x].l,l,mid,L,mid),reset(rp,t[x].r,mid+1,r,mid+1,R);
            gx(p);
        }
    }
    inline void dec(int &p,int x,int u,int d){
        while (u){
            add(p,x,1,n,df[to[u]],df[u],d);x=p;
            u=fa[to[u]];
        }
    }
    inline void work(int &p,int x,int y,int d){
        int u=y,s=-1;
        while (u){
            add(p,x,1,n,df[to[u]],df[u],-d);x=p;
            if (s==-1) s=mask(p,1,n,df[to[u]],df[u]);
            u=fa[to[u]];
        }
        if (s!=-1){
            printf("%d
    ",s-1);
            y=w[s]-ask(p,1,n,df[s]);
            reset(p,p,1,n,df[s],lo[s]);
            dec(p,p,fa[s],y);
        }else puts("0");
    }
    int main(){
        int i;
        T=read();
        while (T--){
            n=read();m=read();n++;w[1]=1e9;NUM=num=nm=0;
            memset(ro,0,sizeof(ro));memset(l,0,sizeof(l));
            for (i=2;i<=n;i++) in(read()+1,i),w[i]=read();
            dfs(1);DFS(1,1);build(ro[0],1,n);
            for (i=1;i<=m;i++){
                x=read();ty=read();
                if (ty==1){
                    y=read()+1;
                    work(ro[i],ro[x],y,read());
                }else{
                    y=read()+1;
                    printf("%d
    ",ty=(w[y]-ask(ro[x],1,n,df[y])));
                    reset(ro[i],ro[x],1,n,df[y],lo[y]);
                    dec(ro[i],ro[i],fa[y],ty);
                }
            }
        }
    }
    View Code
  • 相关阅读:
    ZOJ 3018
    poj2464
    Gauss
    【C】关于内存地址
    【C】typedef与define的区别
    C位移操作
    操作系统使用批处理文件更改网络配置
    【Linux】查看某个进程的线程数量(转)
    数据结构快速排序
    C++Explanation of ++val++ and ++*p++ in C
  • 原文地址:https://www.cnblogs.com/Enceladus/p/7000971.html
Copyright © 2020-2023  润新知