博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

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}\left\lfloor i*e \right\rfloor$

题解:连分数求出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\n",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\n",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

 

posted @ 2017-06-13 14:22  swm_sxt  阅读(317)  评论(0编辑  收藏  举报