zoukankan      html  css  js  c++  java
  • P2709 小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<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    const int N=500005;
    
    int n,m,k;
    int a[N],c[N];
    int ans,Ans[N];
    int belong[N];
    struct Querry
    {
        int tim,l,r;
        bool operator < (const Querry &a) const
        {
            if(belong[l]==belong[a.l]) return belong[r]<belong[a.r];
            return belong[l]<belong[a.l];
        }
    }q[N];
    
    int read()
    {
        char c=getchar();int num=0;
        for(;!isdigit(c);c=getchar());
        for(;isdigit(c);c=getchar())
            num=num*10+c-'0';
        return num;
    }
    
    void init()
    {
        n=read(),m=read(),k=read();
        int size=sqrt(n);
        for(int i=1;i<=n;++i)
            a[i]=read(),
            belong[i]=(i-1)/size+1;
        for(int i=1;i<=m;++i)
            q[i].l=read(),q[i].r=read(),q[i].tim=i;
        sort(q+1,q+m+1);
        
    }
    
    /*void update(int now,bool type)
    {
        if(type)
        {
            ans-=c[now]*c[now];
            ++c[now];
            ans+=c[now]*c[now];
        }
        else
        {
            ans-=c[now]*c[now]; 
            --c[now];
            ans+=c[now]*c[now];
        }
    }*/
    void update(int now,bool type)
    {
        if(type)
            ans+=c[now]<<1|1,++c[now];        //(a+1)*(a+1)==a*a+2*a+1,比a*a多了2*a+1 
        else
            ans-=(c[now]<<1)-1,--c[now];    //(a-1)*(a-1)==a*a-2*a+1,比a*a少了2*a-1 
    }
    
    void work()
    {
        for(int i=q[1].l;i<=q[1].r;++i)
            update(a[i],1);
        Ans[q[1].tim]=ans;
        for(int i=2;i<=m;++i)
        {
            if(q[i].l>q[i-1].l)
                for(int j=q[i-1].l;j<q[i].l;++j)
                    update(a[j],0);
            if(q[i].l<q[i-1].l)
                for(int j=q[i].l;j<q[i-1].l;++j)
                    update(a[j],1);
            if(q[i].r<q[i-1].r)
                for(int j=q[i].r+1;j<=q[i-1].r;++j)
                    update(a[j],0);
            if(q[i].r>q[i-1].r)
                for(int j=q[i-1].r+1;j<=q[i].r;++j)
                    update(a[j],1);
            Ans[q[i].tim]=ans;    
        }
        for(int i=1;i<=m;++i)
            printf("%d
    ",Ans[i]);
    }
    
    int main()
    {
        init();
        work();
        return 0;
    }
  • 相关阅读:
    教你Python3实现12306火车票自动抢票,小白必学
    Spring Security 中如何快速查看登录 IP地址等信息?一招搞定
    方程组及其解的判定
    向量空间
    极大无关组和向量组等价
    向量组的线性相关与线性无关
    向量间的线性关系
    向量的概念和运算
    矩阵的秩和秩的性质
    利用初等变换求逆矩阵和解矩阵方程
  • 原文地址:https://www.cnblogs.com/lovewhy/p/8439741.html
Copyright © 2011-2022 走看看