• bzoj3747: [POI2015]Kinoman


    哇被靖靖D飞啊

    这题做法很是玄学,感觉最近这段时间的确是比较颓,一点写大数据结构的欲望都没有。

    首先先用一个链表存储同一部电影的出现时间。

    然后求前缀和。

    枚举左端点往右延伸,电影的出现次数也减少,判断一下加减的情况即可。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    
    struct trnode
    {
        int l,r,lc,rc;LL c,lazy;
    }tr[2100000];int trlen;
    void bt(int l,int r)
    {
        trlen++;int now=trlen;
        tr[now].l=l;tr[now].r=r;
        tr[now].lc=tr[now].rc=-1;
        tr[now].c=0;tr[now].lazy=0;
        if(l<r)
        {
            int mid=(l+r)/2;
            tr[now].lc=trlen+1;bt(l,mid);
            tr[now].rc=trlen+1;bt(mid+1,r);
            tr[now].c=max(tr[tr[now].lc].c,tr[tr[now].rc].c);
        }
    }
    void change(int now,int l,int r,LL k)
    {
        if(l>r)return ;
        if(tr[now].l==l&&tr[now].r==r)
        {
            tr[now].c+=k;
            tr[now].lazy+=k;
            return ;
        }
        
        int lc=tr[now].lc,rc=tr[now].rc;
        int mid=(tr[now].l+tr[now].r)/2;
        if(tr[now].lazy!=0)
        {
            tr[lc].c+=tr[now].lazy;tr[lc].lazy+=tr[now].lazy;
            tr[rc].c+=tr[now].lazy;tr[rc].lazy+=tr[now].lazy;
            tr[now].lazy=0;
        }
        
        if(r<=mid)change(lc,l,r,k);
        else if(mid+1<=l)change(rc,l,r,k);
        else change(lc,l,mid,k),change(rc,mid+1,r,k);
        
        tr[now].c=max(tr[lc].c,tr[rc].c);
    }
    LL findmax(int now,int l,int r)
    {
        if(tr[now].l==l&&tr[now].r==r)return tr[now].c;
        
        int lc=tr[now].lc,rc=tr[now].rc;
        int mid=(tr[now].l+tr[now].r)/2;
        if(tr[now].lazy!=0)
        {
            tr[lc].c+=tr[now].lazy;tr[lc].lazy+=tr[now].lazy;
            tr[rc].c+=tr[now].lazy;tr[rc].lazy+=tr[now].lazy;
            tr[now].lazy=0;
        }
        if(r<=mid)return findmax(lc,l,r);
        else if(mid+1<=l)return findmax(rc,l,r);
        else return max(findmax(lc,l,mid),findmax(rc,mid+1,r));
    }
    int f[1100000];
    int num[1100000],next[1100000],first[1100000];
    LL s[1100000],w[1100000];
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&f[i]);
        for(int i=1;i<=m;i++)scanf("%d",&w[i]);
        memset(first,0,sizeof(first));
        for(int i=n;i>=1;i--)
        {
            next[i]=first[f[i]];
            first[f[i]]=i;
        }
        for(int i=1;i<=n;i++)
        {
            s[i]=s[i-1];
            if(num[f[i]]==0)s[i]+=w[f[i]];
            if(num[f[i]]==1)s[i]-=w[f[i]];
            num[f[i]]++;
        }
        trlen=0;bt(1,n);
        for(int i=1;i<=n;i++)change(1,i,i,s[i]);
        
        LL ans=0;
        for(int i=1;i<=n;i++)
        {
            ans=max(ans,findmax(1,i,n));
            if(next[i]!=0)
            {
                change(1,i+1,next[i]-1,-w[f[i]]);
                if(next[next[i]]!=0)
                    change(1,next[i],next[next[i]]-1,w[f[i]]);
                else
                    change(1,next[i],n,w[f[i]]);
            }
            else change(1,i+1,n,-w[f[i]]);
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    HDU 1075 What Are You Talking About(字典树)
    HDU 1075 What Are You Talking About (stl之map映射)
    HDU 1247 Hat’s Words(字典树活用)
    字典树HihoCoder
    HDU 1277全文检索(字典树)
    HDU 3294 Girls' research(manachar模板题)
    HDU 3294 Girls' research(manachar模板题)
    HDU 4763 Theme Section(KMP灵活应用)
    Ordering Tasks UVA
    Abbott's Revenge UVA
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8697372.html
Copyright © 2020-2023  润新知