• 【洛谷 2709】小B的询问


    题目描述

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

    输入输出格式

    输入格式:

    第一行,三个整数N、M、K。

    第二行,N个整数,表示小B的序列。

    接下来的M行,每行两个整数L、R。

    输出格式:

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

    输入输出样例

    输入样例#1: 复制
    6 4 3
    1 3 2 1 1 3
    1 4
    2 6
    3 5
    5 6
    输出样例#1: 复制
    6
    9
    5
    2

    说明

    对于全部的数据,1<=N、M、K<=50000

    题解:莫队模板吧,稍加修改

    #include<bits/stdc++.h>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    using namespace std;
    const int N=50005;
    inline int get(){
        int f=1;
        char c=getchar();
        int res=0;
        while (c<'0'||c>'9') {
            if (c=='-') f=-1;
            c=getchar();
        }
        while (c>='0'&&c<='9'){
            res=(res<<3)+(res<<1)+c-'0';
            c=getchar();
        }
        return res*f;
    }
    struct node{
        int l,r,id;
    }e[N];
    int a[N],n,m,jjj[N],f[N],ans,k,kk;
    
    bool cmp(node p,node q){
        if((p.l-1)/kk==(q.l-1)/kk) return p.r<q.r;
        else return (p.l-1)/kk<(q.l-1)/kk;
    }
    
    void add(int x){
        if(++f[x]==1) 
           ans+=2*f[x]-1;
    }
    void remove(int x){
        if(--f[x]==0) 
           ans-=2*f[x]-1;
    }
    int main(){
        freopen("02709.in","r",stdin);
        freopen("02709.out","w",stdout);
        n=get(); m=get(); k=get();
        kk=sqrt(n);
        for(int i=1;i<=n;i++)
            a[i]=get();
        
        for(int i=1;i<=m;i++){
            e[i].l=get();
            e[i].r=get();
            e[i].id=i;
        }
        sort(e+1,e+m+1,cmp);
        int L=1,R=0;
        for(int i=1;i<=m;i++){
            //while(L>e[i].l) add(a[--L]);
            //while(R<e[i].r) add(a[++R]);
            //while(L<e[i].l) remove(a[L++]);
            //while(R>e[i].r) remove(a[R--]);
            while(L>e[i].l) L--,f[a[L]]++,ans+=2*f[a[L]]-1;
            while(R<e[i].r) R++,f[a[R]]++,ans+=2*f[a[R]]-1;
            while(L<e[i].l) f[a[L]]--,ans-=2*f[a[L]]+1,L++;
            while(R>e[i].r) f[a[R]]--,ans-=2*f[a[R]]+1,R--;
            jjj[e[i].id]=ans;
        }
        for(int i=1;i<=m;i++)
            printf("%d
    ",jjj[i]);
        return 0;
    } 
  • 相关阅读:
    前端把html表格生成为excel表格
    图片预加载
    angular开发中的两大问题
    3d图片点击切换
    图片懒加载
    angular排序
    vue1.0 与 Vue2.0的一些区别 及用法
    图片懒加载
    图片放大镜
    图片小精灵 & 解决同时给一个元素设置背景问题 &jq登录注册切换
  • 原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11235072.html
Copyright © 2020-2023  润新知