zoukankan      html  css  js  c++  java
  • [SDOI2009]HH的项链 BZOJ1878

    分析:

    听说是莫队裸题,很显然,我并不喜欢莫队。

    我们可以考虑将询问离线,以右端点排序,之后从1枚举到n,依次树状数组中修改i和last[i],之后当i==询问的右节点时,find一下答案就可以了。

    附上代码:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cmath>
    using namespace std;
    #define N 50005
    #define M 1000005
    int n,m,a[N],last[M];
    struct node
    {
        int l,r,ans,idx;
    }q[N<<2];
    bool cmp(const node &c,const node &b){return c.r<b.r;}
    bool cmp1(const node &a,const node &b){return a.idx<b.idx;}
    int sum[N];
    void fix(int x,int c){for(int i=x;i<=n;i+=i&-i)sum[i]+=c;}
    int find(int x)
    {
        int ret=0;
        for(int i=x;i;i-=i&-i)ret+=sum[i];
        return ret;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        scanf("%d",&m);
        for(int i=1;i<=m;i++)scanf("%d%d",&q[i].l,&q[i].r),q[i].idx=i;
        sort(q+1,q+m+1,cmp);
        int cnt=1;
        for(int i=1;i<=n;i++)
        {
            if(last[a[i]])fix(last[a[i]],-1);
            fix(i,1);
            last[a[i]]=i;
            while(q[cnt].r==i)q[cnt].ans=find(i)-find(q[cnt].l-1),cnt++;
        }
        sort(q+1,q+m+1,cmp1);
        for(int i=1;i<=m;i++)
        {
            printf("%d
    ",q[i].ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    LPC2478中断控制器以及串口详解
    有效三角形的个数
    小于K的两数之和
    和至少为K的最短子数组
    docker: 构建自己的镜像
    判断字符串是否是异位词
    找出字符串中的最长回文
    knuth洗牌算法
    使用adb命令控制anroid手机
    bitmap以及异或运算法
  • 原文地址:https://www.cnblogs.com/Winniechen/p/9107756.html
Copyright © 2011-2022 走看看