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 <= 500000,M <= 200000。

    题解:

    莫队算法入门题之一。

    不赘述,(见我的博客小Z的袜子)

    哪位 dalao 能帮我看看下面的代码怎么优化?洛谷上 T 掉了2个点, BZOJ 上也 T 掉了。感谢了!!!

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=500005,M=200005;
     4 int n,m,block,col[N],belong[N],ans[M],sum,num[N*2];
     5 struct node{
     6     int l,r,id;
     7 }q[M];
     8 inline int read()
     9 {
    10     int x=0,f=1; char ch=getchar();
    11     while (!isdigit(ch))
    12       f=(ch=='-')?-f:f,ch=getchar();
    13     while (isdigit(ch))
    14       x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    15     return x*f;
    16 }
    17 bool cmp(node a,node b)
    18 {
    19     return belong[a.l]==belong[b.l]?(belong[a.r]==belong[b.r]?a.id<b.id:a.r<b.r):a.l<b.l;
    20 }
    21 void revise(int x,int w)
    22 {
    23     num[col[x]]+=w; 
    24     if (w>0) sum+=(num[col[x]]==1);
    25     if (w<0) sum-=(num[col[x]]==0);
    26 }
    27 int main()
    28 {
    29     n=read();
    30     block=sqrt(n);
    31     for (int i=1; i<=n; i++)
    32     {
    33         scanf("%d",&col[i]);
    34         belong[i]=i/block+1;
    35     }
    36     m=read();
    37     for (int i=1; i<=m; i++)
    38     {
    39         int x,y;
    40         x=read(),y=read();
    41         q[i].l=x,q[i].r=y,q[i].id=i;
    42     }
    43     sort(q+1,q+1+m,cmp);
    44     int zl=0,zr=0;
    45     memset(num,0,sizeof(num)); sum=0;
    46     for (int i=1; i<=m; i++)
    47     {
    48         while (zl<q[i].l) revise(zl,-1),zl++;
    49         while (zl>q[i].l) revise(zl-1,1),zl--;
    50         while (zr<q[i].r) revise(zr+1,1),zr++;
    51         while (zr>q[i].r) revise(zr,-1),zr--;
    52         ans[q[i].id]=sum;
    53     }
    54     for (int i=1; i<=m; i++)
    55       printf("%d
    ",ans[i]);
    56     return 0;
    57 }
    View Code

    加油加油加油!!! fighting fighting fighting !!!

  • 相关阅读:
    检测c/c++中内存泄露
    在一个集合S中寻找最大的C使A+B=C且A,B,C均在集合当中
    《为学》
    U盘windows无法格式化的解决办法
    java.lang.AbstractMethodError: oracle.jdbc.driver...解决方法
    sqlplus连接远程Oracle
    oracle字符集导致的乱码问题
    大端与小端存储模式详解
    《劝学》原文
    《报任安书》司马迁
  • 原文地址:https://www.cnblogs.com/Frank-King/p/9167011.html
Copyright © 2011-2022 走看看