zoukankan      html  css  js  c++  java
  • 【Luogu】P2709小B的询问(莫队算法)

      题目链接

      md,1A率等于0.

      烦死。

      终于搞到一道莫队了qwq。

      先对区间分块再按照块编号为第一关键字,右端点为第二关键字排序,然后每次端点移动1乱搞。

      然后……就wa了。

      然后有很多细节需要注意qwq。比如这是个离线算法,在线输出个鬼

      当然更有可能是我太菜了

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<cctype>
    #include<cmath>
    using namespace std;
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    long long nu[51000];
    long long d[1000010];
    int s[1000100];
    int la[1000100];
    int ans[1000100];
    long long sum;
    
    struct Que{
        long long x,y;
        int id;
        bool operator <(const Que a){
            if(s[x]!=s[a.x])    return s[x]<s[a.x];
            else return y<a.y;
        }
    }que[1000010];
    
    int main(){
        int n=read(),m=read(),q=read();
        int b=sqrt(n);
        for(int i=1;i<=n;++i){
            d[i]=read();
            s[i]=(i-1)/b+1;
        }
        for(int i=1;i<=m;++i)    que[i]=(Que){read(),read(),i};
        sort(que+1,que+m+1);
        for(int i=m;i;--i)    la[s[que[i].x]]=i;
        long long sum=1;    nu[0]=1;
        int l=0,r=0;
        for(int j=1;j<=m;++j){
            int x=que[j].x,y=que[j].y;
            while(r<y){
                r++;
                sum-=nu[d[r]]*nu[d[r]];
                nu[d[r]]++;
                sum+=nu[d[r]]*nu[d[r]];
            }
            while(r>y){
                sum-=nu[d[r]]*nu[d[r]];
                nu[d[r]]--;
                sum+=nu[d[r]]*nu[d[r]];
                r--;
            }
            while(l<x){
                sum-=nu[d[l]]*nu[d[l]];
                nu[d[l]]--;
                sum+=nu[d[l]]*nu[d[l]];
                l++;
            }
            while(l>x){
                l--;
                sum-=nu[d[l]]*nu[d[l]];
                nu[d[l]]++;
                sum+=nu[d[l]]*nu[d[l]];
            }
            ans[que[j].id]=sum;
        }
        for(int i=1;i<=m;++i)    printf("%lld
    ",ans[i]);
        return 0;
    }
    
    /*
    6 4 3
    1 3 2 1 1 3
    1 4
    5 6
    3 5
    2 6
    */
  • 相关阅读:
    [zz]redhat6.0无法识别ntfs分区的解决方法
    使用ftp搭建yum源问题解决
    [zz]搭建centos6.0本地yum源(32位)
    JAVA传统线程技术
    JAVA判断字符串是否为数字
    java之异常
    随便记两笔Java中的反射
    【转】单例模式完全解析
    java.lang.Enum
    文件搜索
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/8270596.html
Copyright © 2011-2022 走看看