zoukankan      html  css  js  c++  java
  • BZOJ1878 [SDOI2009] HH的项链(树状数组)

    树状数组求区间不同种类的数模板

    树状数组来存储前缀和,对于每个数我们记录他上一次出现的位置,

    把查询按照右端点从小到大排序

    对于每个数我们对add(pre[i],-1) add(i,1);

    每个数字只有他当前最后一个位置贡献次数(查询区间已排序)

    最后sum[r]-sum[l-1]就是答案

    /**************************************************************
        Problem: 1878
        User: Minun
        Language: C++
        Result: Accepted
        Time:1728 ms
        Memory:10276 kb
    ****************************************************************/
     
    #include<bits/stdc++.h>
      
    using namespace std;
      
    const int maxn=1e6+10;
    const double EPS=1e-12;
      
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
     
    int tree[50005];
    int ans[600005],pre[50005];
     
    int vis[maxn];
     
    int n;
     
    struct node{
        int l,r,id;
    }e[200005];
      
    inline int lowbit(int x)
    {
        return x&(-x);
    }
      
    inline void add(int x,int val)
    {
        while(x<=n)
        {
            tree[x]+=val;
            x+=lowbit(x);
        }
    }
      
    inline int sum(int x)
    {
        int temp=0;
        while(x>0)
        {
            temp+=tree[x];
           // x=x&(x-1);
            x-=lowbit(x);
        }
        return temp;
    }
      
      
      
    int cmp(node a,node b)
    {
        return a.r==b.r?a.l<b.l:a.r<b.r;
    }
      
      
    int main()
    {
    
        scanf("%d",&n);
        int now;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&now);
            pre[i]=vis[now];
            vis[now]=i;
        }
        int m;
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&e[i].l,&e[i].r);
            e[i].id=i;
        }
      
        sort(e+1,e+1+m,cmp);
        int st=1;
        st=0;
        for(int i=1;i<=m;i++)
        {
      
            while(st<e[i].r)
            {
                st++;
                if(pre[st])
                {
      
                    add(pre[st],-1);
                }
                add(st,1);
            }
            ans[e[i].id]=sum(e[i].r)-sum(e[i].l-1);
        }
        for(int i=1;i<=m;i++)
        {
            printf("%d
    ",ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    js中剩余参数
    css中 @mixin的使用
    前端Vue中常用rules校验规则
    vue 运行时报错: Cannot assign to read only property 'exports' of object 'Object'
    webpack 常用的loader
    二维码图片合成 ----合成图片以便微信长按保存(移动端)
    VUE中引入第三方JS
    小程序开发者工具--快捷键
    小程序注意事项
    webpack+ES6+less 开发环境搭建
  • 原文地址:https://www.cnblogs.com/minun/p/10896095.html
Copyright © 2011-2022 走看看