• P2709 小B的询问


    传送门

    莫队

    看一眼感觉是数据结构..

    怎么看都是数据结构...

    但是呢,数据结构要怎么搞我不会啊

    换个思路,莫队

    一下就会搞了..


    稍微讲一下莫队:

    莫队的思路很简单

    首先考虑如果只是询问一个区间

    从区间左边开始,累加答案,一直到右边

    但如果已知一段区间的值,要搞另一段区间的值呢

    首先把已知的区间扩大,更新值,直到把要询问的区间包住

    那多出来的呢

    从多出来的边界开始,往询问的边界靠近,走一步减一次

    走到询问边界后就是答案了

    但是如果是按输入顺序来处理..

    明显会超时..

    那就离线

    先读入,排个序

    让边界的移动次数减小

    至于怎么排序

    有一个套路

    看程序就好

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=50007;
    struct data
    {
        int l,r,id,pos;
        bool operator < (const data &a)
        {
            if(pos!=a.pos) return pos<a.pos;//以pos为第一关键字排序
            return r<a.r;
        }
    }d[N];
    int a[N],cnt[N],n,m,k;
    long long ans[N],res;
    int main()
    {
        cin>>n>>m>>k;
        int t=sqrt(n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&d[i].l,&d[i].r);
            d[i].id=i; d[i].pos=(d[i].l-1)/t+1;//计算pos的套路
        }
        sort(d+1,d+m+1);
        int l=1,r=0;
        for(int i=1;i<=m;i++)
        {
            while(l<d[i].l) res=res-cnt[a[l]]*2+1,cnt[a[l]]--,l++;
            while(r<d[i].r) r++,cnt[a[r]]++,res=res+cnt[a[r]]*2-1;
            while(l>d[i].l) l--,cnt[a[l]]++,res=res+cnt[a[l]]*2-1;
            while(r>d[i].r) res=res-cnt[a[r]]*2+1,cnt[a[r]]--,r--;
             //莫队的基本操作,在纸上画一画就懂了,至于为什么res可以这样跟新应该很显然吧(学过完全平方公式的人都懂...)
            ans[d[i].id]=res;
        }
        for(int i=1;i<=m;i++)
            printf("%lld
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    Linux 防火墙配置
    【存在问题,待修改】SSH 远程登陆
    Hadoop 本地模式安装
    CentOS7 安装 JDK
    JS的DOM操作
    JavaScript
    格式与布局(定位)
    样式表
    表单、内嵌网页
    HTML中的一般标签、常用标签和表格
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9530755.html
Copyright © 2020-2023  润新知