zoukankan      html  css  js  c++  java
  • [题解]luogu_P1972_HH的项链(树状数组/莫队

    原来就做过的题,顺便再看一下写个题解,理解不够深刻

    核心:对于重复出现的数字我们只计算最后出现的那个,其实和计数的一个技巧非常像就是对于可能重复计算的只计算有某特点的那个,防止算重,比较抽象以后再说吧

    所以这题用树状数组记录每个位置的数字是否第一次出现,每次区间查询

    原来的代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define lowbit(x) x&(-x)
    using namespace std;
    const int maxn=500010;
    int n,m;
    int a[maxn],t[maxn],v[2*maxn];
    int nxt[2*maxn];//數字i在此後第一次出現的位置 
    struct node{
        int l,r,id;
    }qq[maxn];int cnt;
    int ans[maxn];
    inline int read()
    {
        int ret=0,fix=1;char ch;
        while(!isdigit(ch=getchar())) fix=ch=='-'? -1:fix;
        do ret=(ret<<1)+(ret<<3)+ch-'0';
        while(isdigit(ch=getchar()));
        return ret*fix;
    }
    inline void add(int x,int num)
    {
        while(x<=n){
            t[x]+=num;
            x+=lowbit(x);
        }
    }
    inline int query(int x)
    {
        int ans=0;
        while(x>0){
            ans+=t[x];
            x-=lowbit(x);
        }
        return ans;
    }
    bool cmp(node a,node b)
    {
        if(a.r!=b.r)return a.r<b.r;
        else return a.l<b.l;
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++){
            a[i]=read();
        }
        m=read();
        for(int i=1;i<=m;i++){
            qq[++cnt].l=read();
            qq[cnt].r=read();
            qq[cnt].id=i;
        }
        sort(qq+1,qq+1+m,cmp);
    //    for(int i=n;i>=1;i--){
    //        if(!v[a[i]])nxt[i]=n+1;
    //        else nxt[i]=v[a[i]];
    //        v[a[i]]=i;
    //    }
    //    for(int i=1;i<=m;i++){
    //        for(;j<q[i].x;j++)
    //        add(nxt[j],1);
    //        ans[qq[i].id]=query(q[i].r)-query(q[i].l-1);
    //    }
        int last=1;
        for(int i=1;i<=m;i++){
            for(int j=last;j<=qq[i].r;j++){
                if(nxt[a[j]])add(nxt[a[j]],-1);
                add(j,1);
                nxt[a[j]]=j;
            }
            last=qq[i].r+1;
            ans[qq[i].id]=query(qq[i].r)-query(qq[i].l-1);
        }
        for(int i=1;i<=m;i++)
        printf("%d
    ",ans[i]);
    }
  • 相关阅读:
    Ubuntu中遇到Unable to lock the administration directory
    Ubuntu使用脚本安装Docker
    Linux shell 批量运行jmeter脚本
    clip原理
    模块化定义JS,让统一文件夹内相同的变量不冲突
    JS中的this都有什么作用?
    jQ中prop与attr的区别
    ;(function( $, window, undefined ){ }(jQuery,window))为何需要往里面传$,window,undefined这些参数
    Asp.Mvc中的text实现 辅助用户输入 灰色字体
    C#List的排序和简单去重总结
  • 原文地址:https://www.cnblogs.com/superminivan/p/11504606.html
Copyright © 2011-2022 走看看