• 洛谷 P2709 小B的询问 (莫队算法)


    传送门

    我的第一道莫队题。

    以后新学一个算法做的第一题尽量都写一个博客。

    其实非常简单,没有什么好讲的。

    反正莫队的核心就是分块排序,然后移动选定区间指针,添加或删除元素嘛。

    当然因为这是一道莫队门槛题,所以比较简单。

    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    #include <string.h>
    #include <algorithm>
    #define MAXN 50010
    using namespace std;
    typedef long long LL;
    int n,m,k,pos[MAXN],a[MAXN],cnt[MAXN];
    LL sum,ans[MAXN];
    struct Ques{
        int l,r,id;
        LL ans;
    }q[MAXN];
    
    bool cmp1(Ques x,Ques y){return pos[x.l]<pos[y.l]||pos[x.l]==pos[y.l]&&x.r<y.r;}
    
    int read(){
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    void add(int x){
        if(x<1||x>k) return;
        sum+=2*cnt[x]+1;
        cnt[x]++; 
    }
    
    void del(int x){
        if(x<1||x>k) return;
        sum-=2*cnt[x]-1;
        cnt[x]--;
    }
    
    int main(){
        n=read();m=read();k=read();
        int sz=sqrt(n);
        for(int i=1;i<=n;i++) a[i]=read(),pos[i]=i/sz;
        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,cmp1);
        int L=0,R=0;
        for(int i=1;i<=m;i++){
            while(R<q[i].r) add(a[R+1]),R++;
            while(R>q[i].r) del(a[R]),R--;
            while(L<q[i].l) del(a[L]),L++;
            while(L>q[i].l) add(a[L-1]),L--;
            ans[q[i].id]=sum;
        }
        for(int i=1;i<=m;i++) printf("%lld
    ",ans[i]);
        return 0;
    } 
  • 相关阅读:
    最容易懂的红黑树
    Chapter 9 (排序)
    【WC2013】糖果公园
    【Luogu1903】数颜色
    【笔记】Sigmoid函数
    【笔记】费马小定理、数论欧拉定理
    【笔记】单层感知机
    2020ICPC.小米 网络选拔赛第一场
    【Luogu3366】模板:最小生成树
    Codeforces Raif Round 1
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/11734473.html
Copyright © 2020-2023  润新知