洛谷P2709 小B的询问 基础莫队

洛谷P2709 小B的询问

标签

  • 莫队

前言

  • 死磕了一个多星期数论,把莫比乌斯反演,狄利克雷卷积,杜教筛,以及一些列和式的运算搞清楚了一些~由于洛谷的数论题都刷完了,所以先回到数据结构!初学莫队鸭

简明题意

  • 求区间[L,R]中所有的数出现次数的平方和

思路

  • 就是基础莫队的基础题了~下面是我的模板:
void add(int x)
{}
void remove(int x)
{}//这两个函数都是用来处理L,R指针移动时对答案的贡献,x是移走/来的点的id
for (int i = 1; i <= m; i++)
{
    while (l < query[i].l) remove(l++);
    while (l > query[i].l) add(--l);
    while (r < query[i].r) add(++r);
    while (r > query[i].r) remove(r--);
    
    ans[query[i].id] = ans;
}
//下面是预处理
int len = sqrt(n);
...
query[i].k = (query[i].l - 1) / len + 1;//k是指块的id
//就这么些~很简单~

注意事项

  • 一开始令l=1,r=0

总结

AC代码

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;

const int maxn = 50000 + 10;

struct Query
{
    int l, r, id, k;
    bool operator < (const Query& a)const
    {
        if (k == a.k) return r < a.r;
        else return k < a.k;
    }
};

int n, m, k, a[maxn];
Query query[maxn];
int ans0[maxn];

int ans, cnt[maxn];
void add(int x)
{
    x = a[x];
    ans += 2 * cnt[x] + 1;
    cnt[x]++;
}
void remove(int x)
{
    x = a[x];
    ans -= 2 * cnt[x] - 1;
    cnt[x]--;
}

void solve()
{
    scanf("%d%d%d", &n, &m, &k);
    int len = (int)sqrt(n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    for (int i = 1; i <= m; i++)
        scanf("%d%d", &query[i].l, &query[i].r), query[i].id = i, query[i].k = (query[i].l - 1) / len + 1;
    sort(query + 1, query + 1 + m);

    int l = 1, r = 0;
    for (int i = 1; i <= m; i++)
    {
        while (l < query[i].l) remove(l++);
        while (l > query[i].l) add(--l);
        while (r < query[i].r) add(++r);
        while (r > query[i].r) remove(r--);
        
        ans0[query[i].id] = ans;
    }

    for (int i = 1; i <= m; i++)
        printf("%d\n", ans0[i]);
}

int main()
{
    solve();
    return 0;
}

转载于:https://www.cnblogs.com/danzh/p/11311931.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值