ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

https://www.hackerrank.com/contests/w31/challenges

Beautiful Word 模拟

Accurate Sorting 检查每个数字距离原位是否都不超过1

Zero-One Game 计算可以被删去的数字个数

Spanning Tree Fraction 最优比率生成树,分数规划+Kruscal

Colliding Circles 算出两两圆之间最后被合并的概率,由期望的线性性计算对答案的贡献

#include<bits/stdc++.h>
typedef long double ld;
int n,k,r[100007];
int main(){
    scanf("%d%d",&n,&k);
    long long s1=0,s2=0;
    for(int i=0;i<n;++i)scanf("%d",r+i),s1+=r[i],s2+=r[i]*r[i];
    ld p=1;
    for(int i=n;i>n-k;--i){
        long long a=1ll*i*(i-1);
        p=p*ld(a-2)/ld(a);
    }
    printf("%.12Lf",acos(-1)*(s2+(s1*s1-s2)*(1-p)));
    return 0;
}
View Code

Nominating Group Leaders 权值分块维护莫队,bzoj原题

#include<bits/stdc++.h>
const int N=1e5+7;
int T,n,m,a[N],as[N],id[N],B,t1[N],t2[N];
struct Q{
    int l,r,x,I;
    bool operator<(Q w)const{
        if(id[l]!=id[w.l])return id[l]<id[w.l];
        if(r!=w.r)return (r<w.r)!=(id[l]&1);
        return I<w.I;
    }
}qs[N];
int cnt[N],*l1[N],*l2[N],*l3[N],*l4[N],*r4[N];
int mem[N*5],*mp;
void ins(int x,int t){
    if(t){
        int a=l1[x][t];
        ++l2[t][a];
        ++l3[t][a>>8];
    }
}
void del(int x,int t){
    if(t){
        int a=l1[x][t];
        --l2[t][a];
        --l3[t][a>>8];
    }
}
int find(int t){
    for(int i=0;i<t2[t];i+=256)if(l3[t][i>>8]){
        int j=i;
        while(!l2[t][j])++j;
        return l4[t][j];
    }
    return -1;
}
void ins(int x){
    del(x,cnt[x]);
    ins(x,++cnt[x]);
}
void del(int x){
    del(x,cnt[x]);
    ins(x,--cnt[x]);
}
int main(){
    for(scanf("%d",&T);T;--T){
        scanf("%d",&n);
        for(int i=0;i<n;++i){
            scanf("%d",a+i);
        }
        mp=mem;
        memset(mem,0,sizeof(mem));
        memset(cnt,0,sizeof(cnt));
        memset(t1,0,sizeof(t1));
        memset(t2,0,sizeof(t2));
        for(int i=0;i<n;++i)++t1[a[i]];
        for(int i=0;i<n;++i)l1[i]=mp-1,mp+=t1[i];
        for(int i=0;i<n;++i){
            for(int j=1;j<=t1[i];++j){
                l1[i][j]=t2[j]++;
            }
        }
        for(int i=1;i<=n;++i){
            l4[i]=r4[i]=mp,mp+=t2[i];
            l3[i]=mp,mp+=t2[i];
            l2[i]=mp,mp+=t2[i];
        }
        for(int i=0;i<n;++i){
            for(int j=1;j<=t1[i];++j){
                *r4[j]++=i;
            }
        }
        scanf("%d",&m);
        B=(n+1)/sqrt(m+1)+1;
        for(int i=0;i<n;++i)id[i]=i/B;
        for(int i=0;i<m;++i){
            scanf("%d%d%d",&qs[i].l,&qs[i].r,&qs[i].x);
            qs[i].I=i;
        }
        std::sort(qs,qs+m);
        int L=0,R=-1;
        for(int i=0;i<m;++i){
            int l=qs[i].l,r=qs[i].r;
            while(L>l)ins(a[--L]);
            while(R<r)ins(a[++R]);
            while(L<l)del(a[L++]);
            while(R>r)del(a[R--]);
            as[qs[i].I]=find(qs[i].x);
        }
        for(int i=0;i<m;++i)printf("%d\n",as[i]);
    }
    return 0;
} 
View Code

Split Plane 由欧拉定理,线段划分出的联通块数=边数-点数+1+线段构成的联通块个数,扫描线处理一下,要开long long !!!

具体实现:横竖各扫一次,计算每条线段与其他线段的交点个数,特判一下端点

用可持久化线段树和并查集维护线段构成的联通块,支持插入、删除一条与扫描线垂直的线段,将当前区间内的线段标记为并起来,细节较多,具体见代码

#include<bits/stdc++.h>
#define int long long
const int N=1e5+7;
struct seg{
    int x,l,r;
    bool operator<(seg w)const{return x!=w.x?x<w.x:l<w.l;}
}s1[N],s2[N],ss[N];
int p1,p2,ans,V,E,C;
int T,n,xs[N*2],ys[N*2],xp=0,yp=0;
void gx(int&x){x=std::lower_bound(xs,xs+xp,x)-xs;}
void gy(int&x){x=std::lower_bound(ys,ys+yp,x)-ys;}

void rb(seg*a,int&ap){
    std::sort(a,a+ap);
    int sp=0;
    for(int i=0,j=0;i<ap;i=j){
        while(j<ap&&a[i].x==a[j].x)++j;
        ss[sp++]=a[i++];
        for(;i<j;++i){
            if(ss[sp-1].r<a[i].l)ss[sp++]=a[i];
            else if(ss[sp-1].r<a[i].r)ss[sp-1].r=a[i].r;
        }
    }
    for(int i=0;i<sp;++i)a[i]=ss[i];
    ap=sp;
}

struct ev{
    int tp,x,a,b;
    bool operator<(ev e)const{return x!=e.x?x<e.x:tp<e.tp;}
}e[N*10];

int t0[N*2],bit[N*2];
void add(int w,int a){
    if(t0[w]==0||t0[w]+a==0)for(int x=w+1;x<N*2;x+=x&-x)bit[x]+=a;
    t0[w]+=a;
}
int sum(int w){
    int s=0;
    for(++w;w;w-=w&-w)s+=bit[w];
    return s;
}
int ch[N*100][2],p,ws[N],f[N*100],pv;
bool fd[N*100],ed[N*100];
int gf(int x){
    int a=x,c;
    while(x!=f[x])x=f[x];
    while(x!=f[a])c=f[a],f[a]=x,a=c;
    return x; 
}
int newnode(){
    ++p;
    ch[p][0]=ch[p][1]=0;
    f[p]=p;
    fd[p]=0;
    ed[p]=0;
    return p;
}
void mg(int a,int b){
    f[gf(a)]=gf(b);
}
void dfs(int w){
    if(fd[w])return;
    fd[w]=1;
    for(int d=0;d<2;++d)if(ch[w][d]){
        mg(w,ch[w][d]);
        dfs(ch[w][d]);
    }
}
void find(int w,int L,int R,int l,int r){
    if(!w)return;
    if(l<=L&&R<=r){
        if(pv)mg(w,pv);
        dfs(w);
        pv=w;
        return;
    }
    int M=L+R>>1;
    if(l<=M)find(ch[w][0],L,M,l,r);
    if(r>M)find(ch[w][1],M+1,R,l,r);
}
int ins(int w,int L,int R,int x,int y){
    int u=newnode();
    if(L==R){
        ws[y]=u;
    }else{
        int M=L+R>>1;
        if(x<=M)ch[u][0]=ins(ch[w][0],L,M,x,y),ch[u][1]=ch[w][1];
        else ch[u][1]=ins(ch[w][1],M+1,R,x,y),ch[u][0]=ch[w][0];
    }
    return u;
}
int del(int w,int L,int R,int x){
    if(L==R)return 0;
    int u=newnode();
    int M=L+R>>1;
    if(x<=M)ch[u][0]=del(ch[w][0],L,M,x),ch[u][1]=ch[w][1];
    else ch[u][1]=del(ch[w][1],M+1,R,x),ch[u][0]=ch[w][0];
    if(!ch[u][0]&&!ch[u][1])return 0;
    return u;
}
void cal(seg*a,int ap,seg*b,int bp,bool cc){
    memset(t0,0,sizeof(t0));
    memset(bit,0,sizeof(bit));
    p=0;
    int rt=newnode();
    int ep=0;
    for(int i=0;i<ap;++i)e[ep++]=(ev){2,a[i].x,a[i].l,a[i].r};
    for(int i=0;i<bp;++i){
        e[ep++]=(ev){1,b[i].l,b[i].x,i};
        e[ep++]=(ev){0,b[i].r+1,b[i].x,i};
    }
    std::sort(e,e+ep);
    for(int i=0;i<ep;++i){
        if(e[i].tp==2){
            int s=sum(e[i].b)-sum(e[i].a-1);
            V+=s;
            E+=s-1;
            if(!t0[e[i].a])V+=2,++E;
            if(!t0[e[i].b])V+=2,++E;
            if(cc&&s){
                pv=0;
                find(rt,0,262143,e[i].a,e[i].b);
                --C;
            }
        }else if(e[i].tp==1){
            add(e[i].a,1);
            if(cc)rt=ins(rt,0,262143,e[i].a,e[i].b);
        }else{
            add(e[i].a,-1);
            if(cc)rt=del(rt,0,262143,e[i].a);
        }
    }
    if(cc)
    for(int i=0;i<bp;++i){
        int a=gf(ws[i]);
        if(!ed[a])ed[a]=1;
        else --C;
    }
}
signed main(){
    for(scanf("%lld",&T);T;--T){
        scanf("%lld",&n);
        p1=p2=0;
        xp=yp=0;
        for(int i=0,x1,y1,x2,y2;i<n;++i){
            scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
            xs[xp++]=x1;
            xs[xp++]=x2;
            ys[yp++]=y1;
            ys[yp++]=y2;
            if(x1>x2)std::swap(x1,x2);
            if(y1>y2)std::swap(y1,y2);
            if(x1==x2)s1[p1++]=(seg){x1,y1,y2};
            else if(y1==y2)s2[p2++]=(seg){y1,x1,x2};
        }
        std::sort(xs,xs+xp);
        xp=std::unique(xs,xs+xp)-xs;
        std::sort(ys,ys+yp);
        yp=std::unique(ys,ys+yp)-ys;
        rb(s1,p1);
        rb(s2,p2);
        for(int i=0;i<p1;++i){
            gx(s1[i].x);
            gy(s1[i].l);
            gy(s1[i].r);
        }
        for(int i=0;i<p2;++i){
            gy(s2[i].x);
            gx(s2[i].l);
            gx(s2[i].r);
        }
        V=E=0;
        C=p1+p2;
        cal(s1,p1,s2,p2,1);
        cal(s2,p2,s1,p1,0);
//        printf("[V=%g E=%d C=%d]",V*.5,E,C);
        printf("%lld\n",E-V/2+1+C);
    }
    return 0;
}
View Code

 

posted on 2017-04-17 17:20  nul  阅读(169)  评论(0编辑  收藏  举报