zoukankan      html  css  js  c++  java
  • BZOJ5011 JXOI2017颜色(主席树)

      相当于求满足在子段中出现的颜色只在该子段中出现的非空子段数量。这也就相当于其中出现的颜色最左出现的位置在左端点右侧,最右出现的位置在右端点左侧。那么若固定某个端点,仅考虑对该端点的限制,会有一段合法区间。这个区间可以二分+st表求出。于是枚举右端点,在其合法区间内查询有多少个合法左端点(即合法区间包括该右端点),上主席树即可。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 300010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    int T,n,a[N],root[N],head[N],tail[N],l[N],r[N],f[N][20],lg2[N],cnt;
    struct data{int l,r,x;
    }tree[N<<5];
    int query(int l,int r)
    {
        if (l>r) return N;
        return min(f[l][lg2[r-l+1]],f[r-(1<<lg2[r-l+1])+1][lg2[r-l+1]]);
    }
    int query2(int l,int r)
    {
        if (l>r) return -1;
        return max(f[l][lg2[r-l+1]],f[r-(1<<lg2[r-l+1])+1][lg2[r-l+1]]);
    }
    void ins(int &k,int l,int r,int x)
    {
        tree[++cnt]=tree[k],k=cnt;tree[k].x++;
        if (l==r) return;
        int mid=l+r>>1;
        if (x<=mid) ins(tree[k].l,l,mid,x);
        else ins(tree[k].r,mid+1,r,x);
    }
    int query(int x,int y,int l,int r,int p,int q)
    {
        if (!y) return 0;
        if (l==p&&r==q) return tree[y].x-tree[x].x;
        int mid=l+r>>1;
        if (q<=mid) return query(tree[x].l,tree[y].l,l,mid,p,q);
        else if (p>mid) return query(tree[x].r,tree[y].r,mid+1,r,p,q);
        else return query(tree[x].l,tree[y].l,l,mid,p,mid)+query(tree[x].r,tree[y].r,mid+1,r,mid+1,q);
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj5011.in","r",stdin);
        freopen("bzoj5011.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        T=read();
        while (T--)
        {
            n=read();
            for (int i=1;i<=n;i++) a[i]=read(),head[i]=n+1,tail[i]=0;
            for (int i=1;i<=n;i++) head[a[i]]=min(head[a[i]],i),tail[a[i]]=max(tail[a[i]],i);
            lg2[1]=0;
            for (int i=2;i<=n;i++)
            {
                lg2[i]=lg2[i-1];
                if ((2<<lg2[i])<=i) lg2[i]++;
            }
            for (int i=1;i<=n;i++) f[i][0]=head[a[i]];
            for (int j=1;j<20;j++)
                for (int i=1;i<=n;i++)
                f[i][j]=min(f[i][j-1],f[min(n,i+(1<<j-1))][j-1]);
            for (int i=1;i<=n;i++)
            {
                int L=i-1,R=n;
                while (L<=R)
                {
                    int mid=L+R>>1;
                    if (query(i,mid)>=i) l[i]=mid,L=mid+1;
                    else R=mid-1;
                }
            }
            for (int i=1;i<=n;i++) f[i][0]=tail[a[i]];
            for (int j=1;j<20;j++)
                for (int i=1;i<=n;i++)
                f[i][j]=max(f[i][j-1],f[min(n,i+(1<<j-1))][j-1]);
            for (int i=1;i<=n;i++)
            {
                int L=1,R=i+1;
                while (L<=R)
                {
                    int mid=L+R>>1;
                    if (query2(mid,i)<=i) r[i]=mid,R=mid-1;
                    else L=mid+1;
                }
            }
            root[0]=0;
            for (int i=1;i<=n;i++)
            {
                root[i]=root[i-1];
                ins(root[i],1,n,l[i]);
            }
            ll ans=0;
            for (int i=1;i<=n;i++)
            ans+=query(root[r[i]-1],root[i],1,n,i,n);
            printf(LL,ans);
        }
        return 0;
    }
  • 相关阅读:
    从零开始入门 K8s | 应用编排与管理
    209. Minimum Size Subarray Sum
    208. Implement Trie (Prefix Tree)
    207. Course Schedule
    203. Remove Linked List Elements
    183. Customers Who Never Order
    182. Duplicate Emails
    181. Employees Earning More Than Their Managers
    1261. Find Elements in a Contaminated Binary Tree
    1260. Shift 2D Grid
  • 原文地址:https://www.cnblogs.com/Gloid/p/10061875.html
Copyright © 2011-2022 走看看