• BZOJ 2038: [2009国家集训队]小Z的袜子(hose)&&莫队算法


    这里跟曼哈顿最小生成树没有太大的关系。

    时间复杂度证明:

    【BZOJ2038 小Z的袜子 AC代码】

    排序方式: 
    第一关键字:l所在的块; 
    第二关键字:r从小到大。

    2017-04-06

    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=2e5+5;
    typedef long long ll;
    struct block{int l,r,id;}Q[N];
    int n,m,bsize,a[N],f[N];
    ll nowans,gg,ans1[N],ans2[N];
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    bool operator <(const block &a,const block &b){
        return a.l/bsize!=b.l/bsize?a.l/bsize<b.l/bsize:a.r<b.r;
    }
    inline void ins(int x){
        nowans+=f[x]++;
    }
    inline void del(int x){
        nowans-=--f[x];
    }
    int main(){
        n=read();m=read();bsize=sqrt(n+0.5);
        for(int i=1;i<=n;i++) a[i]=read();
        for(int i=1;i<=m;i++) Q[i].l=read(),Q[i].r=read(),Q[i].id=i;
        sort(Q+1,Q+m+1);
        int l=1,r=0;
        for(int i=1;i<=m;i++){
            while(l>Q[i].l) ins(a[--l]);
            while(l<Q[i].l) del(a[l++]);
            while(r<Q[i].r) ins(a[++r]);
            while(r>Q[i].r) del(a[r--]);
            ans1[Q[i].id]=nowans;
            ans2[Q[i].id]=1LL*(r-l+1)*(r-l)/2;
        }
        for(int i=1;i<=m;i++){
            if(ans1[i]) gg=__gcd(ans1[i],ans2[i]),printf("%lld/%lld
    ",ans1[i]/gg,ans2[i]/gg);
            else puts("0/1");
        } 
        return 0;
    }
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int N=2e5+7;
    struct node{
        int l,r,t,pos;
        bool operator < (const node &a)const{
            return pos==a.pos?r<a.r:pos<a.pos;
        }
    }b[N];
    int n,m,l,r,a[N],f[N];
    ll res,ans1[N],ans2[N];
    ll gcd(ll a,ll b){
        if(!b) return a;
        return gcd(b,a%b);
    }
    int main(){
        //freopen("hose.in","r",stdin);
        //freopen("hose.out","w",stdout);
        n=read();m=read();
        for(int i=1;i<=n;i++) a[i]=read();
        int k=sqrt(n*1.0)+0.5;
        for(int i=1;i<=m;i++){
            b[i].l=read();b[i].r=read();
            b[i].t=i;b[i].pos=b[i].l/k;
        }
        sort(b+1,b+m+1);
        memset(f,0,sizeof f);
        l=1;r=0;res=0;
        for(int i=1;i<=m;i++){
            while(r>b[i].r){
                res-=(ll)f[a[r]]-1;
                f[a[r]]--;
                r--;
            }
            while(r<b[i].r){
                r++;
                f[a[r]]++;
                res+=(ll)f[a[r]]-1;
            }
            while(l>b[i].l){
                l--;
                f[a[l]]++;
                res+=(ll)f[a[l]]-1;
            }
            while(l<b[i].l){
                res-=(ll)f[a[l]]-1;
                f[a[l]]--;
                l++;
            }
            ans1[b[i].t]=res;
            ans2[b[i].t]=(ll)(r-l+1)*(r-l)/2;
        }
        for(int i=1;i<=m;i++){
            if(!ans1[i]){
                puts("0/1");
                continue;
            }
            ll gg=gcd(ans1[i],ans2[i]);
            printf("%lld/%lld
    ",ans1[i]/gg,ans2[i]/gg);
            //printf("%I64d/%I64d
    ",ans1[i]/gg,ans2[i]/gg);
        }
        return 0;
    }

    reference:

    http://www.cnblogs.com/hzf-sbit/p/4056874.html

  • 相关阅读:
    浅谈自动化测试
    Linux cron定时介绍
    Python上下文管理器
    Robot Framework robot命令
    Web自动化测试之playwright:设置浏览器语言
    Python文件及目录处理方法
    2021google开发者大会
    linux环境变量设置小结
    Eclipse快捷键
    java计时 小计
  • 原文地址:https://www.cnblogs.com/shenben/p/6288840.html
Copyright © 2020-2023  润新知