• 洛谷P1903 [国家集训队]数颜色 / 维护队列


    题目描述

    题解

    第一眼看过去是带修莫队。效率 $O(n^{frac{5}{3}})$ 。可惜洛谷给出的标签是树套树,于是思考一下怎么用数据结构维护。

    如果没有修改的话,我们考虑怎么在线计算答案,考虑到一种颜色只能计算一次,所以可以想到如果 $[l,r]$ 中有的颜色的前驱出现在 $[0,l-1]$ (没有即 $0$ ),那就造成贡献,因此我们可以用主席树维护 $[1,r]$ 中每个位置的前驱对应位置的个数。统计答案的时候就统计 $[l,r]$ 中 $[0,l-1]$ 的标记数即可。

    考虑修改,那我们就用 $ ext{set}$ 维护前驱,然后套树状数组即可。效率 $O(nlog^2n)$ 。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=2e5+5,M=N*200;
    int n,m,t,ls[M],T[N],rs[M],s[M],a[N];
    set<int>st[1000005];
    set<int>::iterator it;char ch[3];
    #define mid ((l+r)>>1)
    void upd(int& x,int l,int r,int p,int v){
        if (!x) x=++t;s[x]+=v;
        if (l==r) return;
        if (mid>=p) upd(ls[x],l,mid,p,v);
        else upd(rs[x],mid+1,r,p,v);
    }
    void upd(int x,int y,int v){
        for (;x<=n;x+=x&-x) upd(T[x],0,n,y,v);
    }
    int qry(int x,int l,int r,int R){
        if (!x) return 0;
        if (r<=R) return s[x];
        if (mid>=R) return qry(ls[x],l,mid,R);
        return s[ls[x]]+qry(rs[x],mid+1,r,R);
    }
    int qry(int l,int r,int p){
        int v=0;
        for (;r;r-=r&-r) v+=qry(T[r],0,n,p);
        for (;l;l-=l&-l) v-=qry(T[l],0,n,p);
        return v;
    }
    int main(){
        cin>>n>>m;
        for (int i=1;i<=n;i++)
            scanf("%d",&a[i]),st[a[i]].insert(i);
        for (int i=1000000;i;i--) st[i].insert(0);
        for (int i=1;i<=n;i++)
            it=st[a[i]].lower_bound(i),it--,upd(i,*it,1);
        for (int u,v,l,r,i=1;i<=m;i++){
            scanf("%s%d%d",ch,&u,&v);
            if (ch[0]=='Q') printf("%d
    ",qry(u-1,v,u-1));
            else{
                st[a[u]].erase(st[a[u]].find(u));
                it=st[a[u]].lower_bound(u);l=r=0;
                if (it!=st[a[u]].end()) r=*it;
                it--;l=*it;upd(u,l,-1);
                if (r) upd(r,u,-1),upd(r,l,1);
                it=st[v].lower_bound(u);l=r=0;
                if (it!=st[v].end()) r=*it;
                it--;l=*it;upd(u,l,1);
                if (r) upd(r,l,-1),upd(r,u,1);
                st[v].insert(u);a[u]=v;
            }
        }
        return 0;
    }
  • 相关阅读:
    天兔(Lepus)监控系统慢查询分析平台安装配置
    java怎么用一行代码初始化ArrayList
    yum命令不能使用的相关错误
    【转】Android APP性能测试
    【转】Java经典问题算法大全
    [转]java中Map,List与Set的区别
    关于编写性能高效的javascript事件的技术
    ESLint 规则
    HTML5 使用application cache 接口实现离线数据缓存
    qunit 前端脚本测试用例
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/12438858.html
Copyright © 2020-2023  润新知