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

    暑假刚学树状数组时就看了这个题,当时挺无头绪的。之后在昨天写了一道区间查询不同个数的模板题,转头发现这个题也是个模板......

    思路:用树状数组维护一个长度为输入总数长度的数组,然后向树状数组输入每一个位置的值,从该位置开始向上更新,每个数组值++,如果这个值在之前最近的位置出现过,所对应的最近位置向上更新,每个数组值--。向下查询的时候返回从下标1位置到当前查询位置所有的不同个数,query(r)-query(l-1)所得到的就是整个区间之内所有不同的数的个数。现在剩下的就是要离线一下,把查询按r的顺序从小到大排一遍,边查询边更新树状数组。

    树状数组难的还是想着怎么维护啊。

    代码写的特别乱,但还是水过了

    #include <set>
    #include <map>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define inf 0x3f3f3f3f
    using namespace std;
    const int Maxn=1000010;
    int pos[Maxn],tree[Maxn],num[Maxn],n,ans[Maxn];
    
    struct st
    {
        int l,r,flag,ans;
    }q[Maxn];
    
    bool cmp(st a, st b)
    {
        return a.r<b.r;
    }
    
    void update(int x,int y,int k)
    {
        if(k==1)
        {
            for(;x<=n;x+=x & (-x)) tree[x]++;
        }
        if(k==2)
        {
            for(;x<=n;x+=x & (-x)) tree[x]--;
            for(;y<=n;y+=y & (-y)) tree[y]++;
        }
    }
    
    int query(int x)
    {
        int ans=0;
        for(;x>0;x-=x & (-x)) ans+=tree[x];
        return ans;
    }
    
    int main()
    {
        int m; scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&num[i]);
        scanf("%d",&m); int l,r;
        for(int i=1;i<=m;i++) {scanf("%d%d",&l,&r); q[i].l=l; q[i].r=r; q[i].flag=i;}
        sort(q+1,q+m+1,cmp); int last=1;
        for(int i=1;i<=m;i++)
        {
            int j; //cout<<i<<" "<<last<<" "<<q[i].r<<endl;
            for(j=last;j<=q[i].r;j++)
            {
                int temp=num[j];
                if(!pos[temp]) update(j,pos[temp],1);
                if(pos[temp]) update(pos[temp],j,2);
                pos[temp]=j;
            }
            //for(int i=1;i<=n;i++) cout<<i<<" "<<tree[i]<<endl;
            last=j;
            //cout<<q[i].flag<<endl;
            //cout<<q[i].l<<" "<<q[i].r<<" ";
            if(q[i].r==q[i].l) ans[q[i].flag]=1;
            else ans[q[i].flag]=query(q[i].r)-query(q[i].l-1);
            //if(q[i].r==q[i].l) cout<<1<<endl;
            //else cout<<query(q[i].r)-query(q[i].l-1)<<endl;
        }
        for(int i=1;i<=m;i++) printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    Sql server 2012 企业中文版安装图文教程
    sql server安装图解
    Unknown custom element: <swiper>
    CSS3实现鼠标移动到图片上图片变大(缓慢变大,有过渡效果,放大的过程是有动画过渡的,这个过渡的时间可以自定义)
    在vue中使用animate.css
    linux配置jdk
    orcal解决锁表
    java 基础知识
    fastjson解析list ,object中含有list, object中含有map
    vue的周期函数
  • 原文地址:https://www.cnblogs.com/benzikun/p/11629164.html
Copyright © 2011-2022 走看看