• 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;
    }
  • 相关阅读:
    Ubuntu中文乱码问题解决方案
    微软开业网站----精华 http://www.microsoft.com/opensource/directory.aspx
    微软开源项目
    cnblogs开源合集
    微软开源软件---管理员用的软件
    微软开源项目-codeflex项目介绍
    SQLServer 微软团队开源项目 (web 版?)
    流程引擎2-CCFLOW
    流程引擎1-高人
    sql web Admin 源码.net 升级
  • 原文地址:https://www.cnblogs.com/minun/p/10896095.html
Copyright © 2020-2023  润新知