zoukankan      html  css  js  c++  java
  • 洛谷 P1972 [SDOI2009]HH的项链【莫队算法学习】

    P1972 [SDOI2009]HH的项链

    题目背景

    题目描述

    HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH 不断地收集新的贝壳,因此,他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答……因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题。

    输入输出格式

    输入格式:

    第一行:一个整数N,表示项链的长度。

    第二行:N 个整数,表示依次表示项链中贝壳的编号(编号为0 到1000000 之间的整数)。

    第三行:一个整数M,表示HH 询问的个数。

    接下来M 行:每行两个整数,L 和R(1 ≤ L ≤ R ≤ N),表示询问的区间。

    输出格式:

    M 行,每行一个整数,依次表示询问对应的答案。

    输入输出样例

    输入样例#1:
    6
    1 2 3 4 3 5
    3
    1 2
    3 5
    2 6
    
    输出样例#1:
    2
    2
    4

    说明

    数据范围:

    对于100%的数据,N <= 50000,M <= 200000。

    题目链接:https://www.luogu.org/problem/show?pid=1972

    分析:莫队算法经典题,算是模版题吧!学习一下!

    下面给出AC代码:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int maxn=1001010;
      4 typedef long long ll;
      5 int n,m,unit;
      6 inline int read()
      7 {
      8     int x=0,f=1;
      9     char ch=getchar();
     10     while(ch<'0'||ch>'9')
     11     {
     12         if(ch=='-')
     13             f=-1;
     14         ch=getchar();
     15     }
     16     while(ch>='0'&&ch<='9')
     17     {
     18         x=x*10+ch-'0';
     19         ch=getchar();
     20     }
     21     return x*f;
     22 }
     23 inline void write(int x)
     24 {
     25     if(x<0)
     26     {
     27         putchar('-');
     28         x=-x;
     29     }
     30     if(x>9)
     31     {
     32         write(x/10);
     33     }
     34     putchar(x%10+'0');
     35 }
     36 struct Query
     37 {
     38     int L,R,id;
     39 }node[maxn];
     40 ll gcd(ll a,ll b)///求最大公约数
     41 {
     42     return b==0?a:gcd(b,a%b);
     43 }
     44 struct Ans
     45 {
     46     ll a,b;
     47     void reduce()///分数简化操作
     48     {
     49         ll d=gcd(a,b);
     50         a/=d;
     51         b/=d;
     52     }
     53 }ans[maxn];
     54 bool cmp(Query a,Query b)///把1~n分成sqrt(n)段,unit=sqrt(n)m个查询先按照第几个块排序,再按照R排序,分块处理
     55 {
     56     if(a.L/unit!=b.L/unit)
     57         return a.L/unit<b.L/unit;
     58     else return a.R<b.R;
     59 }
     60 int a[maxn];
     61 int num[maxn];
     62 inline void work()
     63 {
     64     ll temp=0;
     65     memset(num,false,sizeof(num));
     66     int L=1;
     67     int R=0;
     68     for(int i=0;i<m;i++)///莫队算法核心部分
     69     {
     70         while(R<node[i].R)
     71         {
     72             R++;
     73             ///temp-=(ll)num[a[R]]*num[a[R]];
     74             ///num[a[R]]++;
     75             ///temp+=(ll)num[a[R]]*num[a[R]];
     76             if(!num[a[R]])
     77                 temp++;
     78             num[a[R]]++;
     79         }
     80         while(R>node[i].R)
     81         {
     82             ///temp-=(ll)num[a[R]]*num[a[R]];
     83             num[a[R]]--;
     84             ///temp+=(ll)num[a[R]]*num[a[R]];
     85             ///R--;
     86             if(!num[a[R]])
     87                 temp--;
     88             R--;
     89         }
     90         while(L<node[i].L)
     91         {
     92             ///temp-=(ll)num[a[L]]*num[a[L]];
     93             num[a[L]]--;
     94             ///temp+=(ll)num[a[L]]*num[a[L]];
     95             ///L++;
     96             if(!num[a[L]])
     97                 temp--;
     98             L++;
     99         }
    100         while(L>node[i].L)
    101         {
    102             L--;
    103             ///temp-=(ll)num[a[L]]*num[a[L]];
    104             ///num[a[L]]++;
    105             ///temp+=(ll)num[a[L]]*num[a[L]];
    106             if(!num[a[L]])
    107                 temp++;
    108             num[a[L]]++;
    109         }
    110         ans[node[i].id].a=temp;
    111         ///ans[node[i].id].b=(ll)(R-L+1)*(R-L);
    112         ///ans[node[i].id].reduce();
    113     }
    114 }
    115 int main()
    116 {
    117     n=read();
    118     for(int i=1;i<=n;i++)
    119         a[i]=read();
    120     m=read();
    121     for(int i=0;i<m;i++)
    122     {
    123         node[i].id=i;
    124         node[i].L=read();
    125         node[i].R=read();
    126     }
    127     unit=(int)sqrt(n);
    128     sort(node,node+m,cmp);
    129     work();
    130     for(int i=0;i<m;i++)
    131         printf("%lld
    ",ans[i].a);
    132     return 0;
    133 }
  • 相关阅读:
    jmeter测试mysql数据库之JDBC请求
    接口测试浅谈
    python import xxx 与 from xxx import xx 模块引入的区别
    交互模式下测试python代码及变量的四则运算
    python入门之一python安装及程序运行
    zabbix命令之:zabbix_get命令
    snmpwalk工具使用
    zabbix基础知识
    Centos7.5 rpm安装zabbix_agent4.0.3
    mysql常用命令
  • 原文地址:https://www.cnblogs.com/ECJTUACM-873284962/p/7117059.html
Copyright © 2011-2022 走看看