luogu P2709 小B的询问

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/pretend_fal/article/details/78081575

原题位置: 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;

阅读更多

没有更多推荐了,返回首页