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个询问的答案

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;i++)
#define lv(i,a,n) for(register int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
const int INF = 1 << 30;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
    char c;
    bool op = 0;
    while(c = getchar(), c < ‘0‘ || c > ‘9‘)
        if(c == ‘-‘) op = 1;
    x = c - ‘0‘;
    while(c = getchar(), c >= ‘0‘ && c <= ‘9‘)
        x = x * 10 + c - ‘0‘;
    if(op) x = -x;
}
template <class T>
void write(T x)
{
    if(x < 0) putchar(‘-‘), x = -x;
    if(x >= 10) write(x / 10);
    putchar(‘0‘ + x % 10);
}
struct node
{
    int l,r,id,pos;
}a[50005];
int blo,n,m,k;
ll b[50005],num[56000];
ll cnt[50005];
bool cmp(node a,node b)
{
    if(a.pos != b.pos) return a.pos < b.pos;
    else
    return a.r < b.r;
}
int main()
{
    read(n);read(m);read(k);
    blo = sqrt(n);
    duke(i,1,n)
    {
        read(b[i]);
    }
    duke(i,1,m)
    {
        read(a[i].l);
        read(a[i].r);
        a[i].id = i;
        a[i].pos = (a[i].l - 1) / blo + 1;
    }
    sort(a + 1,a + m + 1,cmp);
    int l  = 1,r = 0;
    ll ans = 0;
    duke(i,1,m)
    {
        while(l > a[i].l) l--,cnt[b[l]]++,ans += 2 * cnt[b[l]] - 1;
        while(r < a[i].r) r++,cnt[b[r]]++,ans += 2 * cnt[b[r]] - 1;
        while(l < a[i].l) cnt[b[l]]--,ans -= 2 * cnt[b[l]] + 1,l++;
        while(r > a[i].r) cnt[b[r]]--,ans -= 2 * cnt[b[r]] + 1,r--;
        num[a[i].id] = ans;
    }
    duke(i,1,m)
    {
        printf("%lld\n",num[i]);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/DukeLv/p/9868587.html

时间: 2024-11-08 19:21:11

P2709 小B的询问 莫队的相关文章

[BZOJ3781][P2709]小B的询问[莫队]

入门题 对于一个区间的询问,如果在已知\([l,r]\)的答案时可以用O(1)的时间求出左右端点\(±1\)的答案,就可以使用莫队来优化. 设已知区间为\([l_1,r_1]\),所求区间为\([l_2,r_2]\) 可知求得\([l_2,r_2]\)的成本是\(|l_1-l_2| + |r_1-r_2|\)如果把这两个区间看成点,这个成本就是两点的曼哈顿距离, 对于多个询问,求出曼哈顿距离最小生成树就可以以最小成本获得答案,使用一种奇怪的方式 --sort来获得最优的转移方式 我并不知道原理

P2709 小B的询问 莫队算法

题意:小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数.小B请你帮助他回答询问. 就是求区间不同数字个数的平方和 注意平方数可以拆开从1-n 递推... #include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<

luoguP2709 小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

小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

BZOJ 3781 小B的询问 莫队算法

题目大意:一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数. 思路:莫队走起. CODE: #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 50010 using namespac

Bzoj 3781: 小B的询问 莫队,分块,暴力

3781: 小B的询问 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 426  Solved: 284[Submit][Status][Discuss] Description 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数.小B请你帮助他回答询问. Input 第一行,三个整数N.M.K. 第二行

P2709 小B的询问 【普通莫队】

这是我的莫队入门题,我也了解到了莫队分为普通莫队以及带修莫队.顾名思义,普通莫队不需要修改区间的值,而带修莫队处理区间的值会修改的查询. 能用莫队的前提条件: 1.在知道 [l, r]中信息时,可以在 O(1)的复杂度内知道 [l - 1, r],[l + 1, r],[l, r - 1],[l, r + 1]的信息,否则复杂度会爆炸. 2.能离线处理. 莫队的时间复杂度为O(n ^ 1.5),但实际效果一定会优于这个时间复杂度. 莫队的主要操作: 1.对查询区间,以 left 来进行分块,然后

清橙A1206 小Z的袜子(莫队算法)

A1206. 小Z的袜子 时间限制:1.0s   内存限制:512.0MB 总提交次数:744   AC次数:210   平均分:44.44 将本题分享到: 查看未格式化的试题   提交   试题讨论 试题来源 2010中国国家集训队命题答辩 问题描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只袜子是不是

洛谷 P2709 小B的询问

https://www.luogu.org/problem/show?pid=2709 题目描述 小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行的整数表