• 【洛谷P2709】小B的询问


    题目链接

    小B的询问

    题目描述

    小B有一个序列,包含(N)(1)~(K)之间的整数。他一共有(M)个询问,每个询问给定一个区间([L..R]),求(sum^{K}_{i=1}{c(i)^2})的值,其中i的值从(1)(K),其中(c(i))表示数字(i)([L..R])中的重复次数。小B请你帮助他回答询问。

    输入格式

    第一行,三个整数(N)(M)(K)
    第二行,(N)个整数,表示小B的序列。
    接下来的(M)行,每行两个整数(L)(R)

    输出格式

    (M)行,每行一个整数,其中第(i)行的整数表示第(i)个询问的答案。

    样例输入

    6 4 3
    1 3 2 1 1 3
    1 4
    2 6
    3 5
    5 6
    

    样例输出

    6
    9
    5
    2
    

    说明/提示

    对于全部的数据,(1 le N)(M)(K le 50000)

    题解

    一道莫队板题(说不定也可以用其他方法做,但是我太菜了,只会莫队)。
    我们用(cnt[j])(l,r)维护(l)(r)区间内(j)这个数字的个数,并且维护一个(ans)值,然后我们移动(l)(r)的时候快速地维护这个数组和(ans)值((ans)值先减去原本的值的平方,再加上新的值的平方)。
    把式子化简之后就是:

    • 如果(cnt_i)多了一个,那(ans+=2*cnt[x]+1)
    • 如果(cnt_i)少了一个,那(ans-=2*cnt[x]-1)

    然后我们把询问中(frac {l}{sqrt{n}})相同的数分为一组(这里分块的大小是(sqrt{n}),一般来说随机数据的话区(sqrt{n})会比较好,但是不同的题目分块的大小也可以不同)
    然后在同一组内的询问,我们按照询问的(r)值从小到大排序。
    这样排序后暴搜的时间复杂度就变成了(O(nsqrt{n}))了,能过此题。
    上代码:

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,k;
    int a[1000009];
    struct aa{
        int l,r,x,ans;
    }p[1000009];
    int sq;
    bool cmp(aa x,aa y){
        if(x.l/sq<y.l/sq) return 1;
        if(x.l/sq>y.l/sq) return 0;
        return x.r<y.r;
    }
    int cnt[1000009];
    bool cmpp(aa x,aa y){return x.x<y.x;}
    int main(){
        scanf("%d%d%d",&n,&m,&k);
        sq=sqrt(n);
        for(int j=1;j<=n;j++)
            scanf("%d",&a[j]);
        for(int j=1;j<=m;j++){
            scanf("%d%d",&p[j].l,&p[j].r);
            p[j].x=j;
        }
        sort(p+1,p+m+1,cmp);
        int ll=1,rr=1,ss=1;
        cnt[a[1]]=1;
        for(int j=1;j<=m;j++){
            while(rr<p[j].r){
                rr++;
                ss-=cnt[a[rr]]*cnt[a[rr]];
                cnt[a[rr]]++;
                ss+=cnt[a[rr]]*cnt[a[rr]];
            }
            while(ll>p[j].l){
                ll--;
                ss-=cnt[a[ll]]*cnt[a[ll]];
                cnt[a[ll]]++;
                ss+=cnt[a[ll]]*cnt[a[ll]];
            }
            while(rr>p[j].r){
                ss-=cnt[a[rr]]*cnt[a[rr]];
                cnt[a[rr]]--;
                ss+=cnt[a[rr]]*cnt[a[rr]];
                rr--;
            }
            while(ll<p[j].l){
                ss-=cnt[a[ll]]*cnt[a[ll]];
                cnt[a[ll]]--;
                ss+=cnt[a[ll]]*cnt[a[ll]];
                ll++;
            }
            p[j].ans=ss;
        }
        sort(p+1,p+m+1,cmpp);
        for(int j=1;j<=m;j++)
            printf("%d
    ",p[j].ans);
        return 0;
    }
    
  • 相关阅读:
    1028. Hanoi Tower Sequence
    sicily 1063. Who's the Boss
    ubuntu 12.04 x86_64:java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons
    ubuntu12.04 desktop默认无ssh支持
    取消putty右键粘贴功能
    gcc编译参数之m32 m64
    Invalid command 'RailsBaseURI'
    Ubuntu 12.4 server 安装 redmine
    查看Samba用户的方法
    【转】windows浏览共享切换用户登录的方法
  • 原文地址:https://www.cnblogs.com/linjiale/p/11764942.html
Copyright © 2020-2023  润新知