luogu P2709 小B的询问

原题位置: https://www.luogu.org/problem/show?pid=2709

这道题是莫队,据说在离线区间查询上,莫队无敌,但是感觉还好吧;

首先这道题是一个用来练手的好题,因为这是板子题;

所以主要就是排序,然后while查询;

至于排序方式 :

首先 ,应用分块思想,以查询左端点所在块为第一关键字, 以右端点为第二关键字 ,均从小到大排序;

然后就没有然后了;

———————–分割线啊——————————–

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define II int
#define R register
#define I 123456
using namespace std;


struct node {
    II l,r,wei;
}aa[I];

II kuan, ans,n,m,k,l=1,r=0;

II c[I], kaa[I], a[I];

bool maP(node a1,node a2) 
{
    if(a1.l/kuan==a2.l/kuan) return a1.r<a2.r;
      return a1.l/kuan<a2.l/kuan;
}


void add(R II x)
{
    x=a[x];
    ans-=c[x]*c[x];
    c[x]++;
    ans+=c[x]*c[x];
}

void dle(R II x)
{
    x=a[x];
    ans-=c[x]*c[x];
    c[x]--;
    ans+=c[x]*c[x];
}


int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(R II i=1;i<=n;i++) scanf("%d",&a[i]);
    for(R II i=1;i<=m;i++) scanf("%d%d",&aa[i].l,&aa[i].r), aa[i].wei=i;

    kuan=sqrt(n);
    sort(aa+1,aa+m+1,maP);

    for(R II i=1;i<=n;i++)
    {
        while (r<aa[i].r) add(++r);// cout<<ans<<" ";
        while (r>aa[i].r) dle(r--);// cout<<ans<<" ";
        while (l<aa[i].l) dle(l++);// cout<<ans<<" ";
        while (l>aa[i].l) add(--l);// cout<<ans<<" ";
        // 每次更改时更新ans;
        //cout<<endl;
        kaa[aa[i].wei]=ans;
    }

    for(R II i=1;i<=m;i++) printf("%d\n",kaa[i]);
    exit(0);
}

————————————-文末分割线————————————–

by pretend-fal

END;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值