zoukankan      html  css  js  c++  java
  • JXOI2017颜色 解题报告

    JXOI2017颜色

    • 首先记录每个位置上颜色在序列中上次出现的位置
    • 开两颗线段树,第一棵维护区间最大值,实际上是维护当前必须被删去的颜色的位置的最大值,第二棵则是维护区间和
    • 首先倒着扫一遍,对于当前颜色的后面一个颜色,将其删去,那他的(pre)肯定也要删去,将其(pre)的位置加入第一棵线段树,对每个位置记一个(able),值为当前第一棵线段树中最大值,表示当前点到(able+1)这一段区间都是可以的。
    • 初始化第二颗树,(sum)值初始设为1,对于每个位置,如果他有前驱,那他与他前驱中这段的颜色不能计入答案,将其全部设为0,统计(i)(able+1)的值即可。
    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    using namespace std;
    typedef int sign;
    typedef long long ll;
    #define For(i,a,b) for(register sign i=(sign)a;i<=(sign)b;++i)
    #define Fordown(i,a,b) for(register sign i=(sign)a;i>=(sign)b;--i)
    const int N=3e5+5;
    bool cmax(sign &a,sign b){return (a<b)?a=b,1:0;}
    bool cmin(sign &a,sign b){return (a>b)?a=b,1:0;}
    template<typename T>inline T read()
    {
        T f=1,ans=0;
        char ch=getchar();
        while(!isdigit(ch)&&ch!='-')ch=getchar();
        if(ch=='-')f=-1,ch=getchar();
        while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch-'0'),ch=getchar();
        return ans*f;
    }
    template<typename T>inline void write(T x,char y)
    {
        if(x==0)
        {
            putchar('0');putchar(y);
            return;
        }
        if(x<0)
        {
            putchar('-');
            x=-x;
        }
        static char wr[20];
        int top=0;
        for(;x;x/=10)wr[++top]=x%10+'0';
        while(top)putchar(wr[top--]);
        putchar(y);
    }
    void file()
    {
        #ifndef ONLINE_JUDGE
            freopen("4056.in","r",stdin);
            freopen("4056.out","w",stdout);
        #endif
    }
    #define lson h<<1,l,mid
    #define rson h<<1|1,mid+1,r
    namespace T1
    {
        int maxn[N<<2];
        void build(int h,int l,int r)
        {
            maxn[h]=0;
            if(l==r)return;
            int mid=(l+r)>>1;
            build(lson);build(rson);
        }
        void update(int h,int l,int r,int pos,int v)
        {
            if(l==r)
            {
                maxn[h]=v;
                return;
            }
            int mid=(l+r)>>1;
            if(pos<=mid)update(lson,pos,v);
            else update(rson,pos,v);
            maxn[h]=max(maxn[h<<1],maxn[h<<1|1]);
        }
    }
    namespace T2
    {
        int sum[N<<2],lazy[N<<2];
        void push_down(int h)
        {
            if(!lazy[h])return;
            int ls=h<<1,rs=ls|1;
            lazy[ls]=lazy[rs]=1;
            sum[ls]=sum[rs]=0;
            lazy[h]=0;
        }
        void build(int h,int l,int r)
        {
            sum[h]=1;lazy[h]=0;
            if(l==r)return;
            int mid=(l+r)>>1;
            build(lson);build(rson);
            sum[h]=sum[h<<1]+sum[h<<1|1];
        }
        void update(int h,int l,int r,int s,int t)
        {
            if(s<=l&&r<=t)
            {
                sum[h]=0;lazy[h]=1;
                return;
            }
            push_down(h);
            int mid=(l+r)>>1;
            if(s<=mid)update(lson,s,t);
            if(mid<t)update(rson,s,t);
            sum[h]=sum[h<<1]+sum[h<<1|1];
        }
        int query(int h,int l,int r,int s,int t)
        {
            if(s<=l&&r<=t)return sum[h];
            push_down(h);
            int res=0,mid=(l+r)>>1;
            if(s<=mid)res=query(lson,s,t);
            if(mid<t)res+=query(rson,s,t);
            sum[h]=sum[h<<1]+sum[h<<1|1];
            return res;
        }
    }
    ll ans;
    int n,m,a[N];
    int pos[N],pre[N],able[N];
    void input()
    {
        n=read<int>();
        For(i,1,n)
        {
            a[i]=read<int>();cmax(m,a[i]);
            pre[i]=pos[a[i]];pos[a[i]]=i;
        }
    }
    void init()
    {
        m=0;ans=0;
        memset(pos,0,sizeof pos);
        memset(able,0,sizeof able);
        memset(pre,0,sizeof pre);
    }
    void work()
    {
        T1::build(1,1,m);
        T2::build(1,1,n);
        Fordown(i,n,1)
        {
            if(i<n)T1::update(1,1,m,a[i+1],pre[i+1]);
            able[i]=T1::maxn[1];
        }
        For(i,1,n)
        {
            if(pre[i])T2::update(1,1,n,pre[i]+1,i);
            if(able[i]+1<=i)ans+=T2::query(1,1,n,able[i]+1,i);
        }
        write(ans,'
    ');
    }
    int main()
    {
        file();
        int T=read<int>();
        while(T--)
        {
            init();
            input();
            work();
        }
        return 0;
    }
    
  • 相关阅读:
    学习:SilverLight学习资源
    学习:ASP.NET 页生命周期概述(转)
    学习:Sharepoint2010 List View Filter: date
    学习:Linq学习资源
    总结:免费电子书下载地址
    总结:SharePoint Designer 2010 DVWP (1) 概述 XsltListViewWebPart和DataFormWebPart
    总结:SharePoint Designer 2010 DVWP (2) DataFormWebPart 不同类型的Column对应的XSLT写法
    Spread For Web Forms 3.0 依然无可匹敌
    ComponentOne Studio Enterprise 2007 产品集合
    GTP.NET项目管理甘特图模块
  • 原文地址:https://www.cnblogs.com/dengyixuan/p/8340355.html
Copyright © 2011-2022 走看看