zoukankan      html  css  js  c++  java
  • 莫队算法。

     https://blog.csdn.net/qq_38891827/article/details/82190013 很多例题

    https://blog.csdn.net/qq_41117236/article/details/81453534

    https://www.lydsy.com/JudgeOnline/problem.php?id=2038

    不带修改的莫队。数区间内有多少个相同的元素。分块大小为n的1/2次方。复杂度为O(n的3/2次方)

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=50000+10;
    int col[maxn],Be[maxn];
    ll sum[maxn],ans;
    struct Mo{
        int l,r,ID;
        ll A,B;
    }f[maxn];
    ll GCD(ll a,ll b){return b==0?a:GCD(b,a%b);}
    bool cmp(Mo a,Mo b){return Be[a.l]==Be[b.l]?a.r<b.r:a.l<b.l;}
    bool CMP(Mo a,Mo b){return a.ID<b.ID;}
    void revise(int x,int add)
    {
        ans-=sum[col[x]]*(sum[col[x]]-1);
        sum[col[x]]+=add;
        ans+=sum[col[x]]*(sum[col[x]]-1);
    }
    int main()
    {
        int n,m; scanf("%d%d",&n,&m);
        int unit=sqrt(n);
        for(int i=1;i<=n;i++)
            scanf("%d",&col[i]),Be[i]=i/unit+1;
        for(int i=1;i<=m;i++)
            scanf("%d%d",&f[i].l,&f[i].r),f[i].ID=i;
        sort(f+1,f+m+1,cmp);
        int l=1,r=0;
        for(int i=1;i<=m;i++){
            while(l<f[i].l) revise(l,-1),l++;
            while(l>f[i].l) revise(l-1,1),l--;
            while(r<f[i].r) revise(r+1,1),r++;
            while(r>f[i].r) revise(r,-1),r--;
            if(f[i].l==f[i].r){
                f[i].A=0;
                f[i].B=1;
                continue;
            }
            f[i].A=ans;
            f[i].B=1LL*(f[i].r-f[i].l+1)*(f[i].r-f[i].l); //分母:len*(len-1)
            ll gcd=GCD(f[i].A,f[i].B);
            f[i].A/=gcd;
            f[i].B/=gcd;
        }
        sort(f+1,f+m+1,CMP);
        for(int i=1;i<=m;i++)
            printf("%lld/%lld
    ",f[i].A,f[i].B);
        return 0;
    }

    https://www.lydsy.com/JudgeOnline/problem.php?id=2120

    待修改的莫队,分块大小为n的2/3次方,时间复杂度为O(n的5/3次方)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=10000+10;
    struct Query{
        int l,r,Tim,ID;
    }q[maxn];
    struct Change{
        int pos,New,Old;
    }c[maxn];
    int s[maxn],Be[maxn];
    int now[maxn],ans[maxn];
    int color[maxn*100];
    int Ans,l=1,r;
    bool cmp(Query a,Query b)
    {
        return Be[a.l]==Be[b.l]?(Be[a.r]==Be[b.r]?a.Tim<b.Tim:a.r<b.r):a.l<b.l;
    }
    void revise(int x,int d)
    {
        color[x]+=d;
        if(d>0) Ans+=color[x]==1;
        if(d<0) Ans-=color[x]==0;
    }
    void going(int x,int d)
    {
        if(l<=x&&x<=r) revise(d,1),revise(s[x],-1);
        s[x]=d;
    }
    int main()
    {
        int n,m; scanf("%d%d",&n,&m);
        int unit=pow(n,2.0/3); 
        for(int i=1;i<=n;i++){
            scanf("%d",&s[i]);
            now[i]=s[i];
            Be[i]=i/unit+1; //分块
        }
        int Time=0,t=0;
        while(m--){
            char sign; int x,y;
            scanf(" %c %d%d",&sign,&x,&y);
            if(sign=='Q') q[++t]=(Query){x,y,Time,t};
            else c[++Time]=(Change){x,y,now[x]},now[x]=y;
        }
        sort(q+1,q+t+1,cmp);
        int T=0;
        for(int i=1;i<=t;i++){
            while(T<q[i].Tim) going(c[T+1].pos,c[T+1].New),T++;
            while(T>q[i].Tim) going(c[T].pos,c[T].Old),T--;
            while(l<q[i].l) revise(s[l],-1),l++;
            while(l>q[i].l) revise(s[l-1],1),l--;
            while(r<q[i].r) revise(s[r+1],1),r++;
            while(r>q[i].r) revise(s[r],-1),r--;
            ans[q[i].ID]=Ans;
        }
        for(int i=1;i<=t;i++) 
            printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    Linux学习50 进程优先级、网络客户端工具、shell循环(续Linux学习49)
    Linux学习51 CentOS系统启动流程介绍
    Linux学习49 资源管理三板斧-htop、vmstat、dstat实战
    【Kafka】CAP理论以及CAP定律
    【Kafka】Flume整合Kafka
    【Kafka】配置文件说明
    【Kafka】JavaAPI操作
    【Kafka】Stream API
    【Kafka】Consumer API
    【Kafka】Producer API
  • 原文地址:https://www.cnblogs.com/downrainsun/p/11279243.html
Copyright © 2011-2022 走看看