zoukankan      html  css  js  c++  java
  • 【数据结构】bzoj3747Kinoman

    Description

    共有m部电影,编号为1~m,第i部电影的好看值为w[i]。
    在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部。
    你可以选择l,r(1<=l<=r<=n),并观看第l,l+1,…,r天内所有的电影。如果同一部电影你观看多于一次,你会感到无聊,于是无法获得这部电影的好看值。所以你希望最大化观看且仅观看过一次的电影的好看值的总和。

    Input

    第一行两个整数n,m(1<=m<=n<=1000000)。
    第二行包含n个整数f[1],f[2],…,f[n](1<=f[i]<=m)。
    第三行包含m个整数w[1],w[2],…,w[m](1<=w[j]<=1000000)。

    Output

    输出观看且仅观看过一次的电影的好看值的总和的最大值。

    Sample Input

    9 4
    2 3 1 1 4 1 2 4 1
    5 3 6 6

    Sample Output

    15
    样例解释:
    观看第2,3,4,5,6,7天内放映的电影,其中看且仅看过一次的电影的编号为2,3,4。
     
     
    =========================================华丽丽的分割线===============================================
    没什么难的吧,直接枚举左端点,然后右端点用一个线段树维护出最大值。
    每一次改变左端点的时候,总会有一些点的值改变,然后发现就是几个区间修改。
    然后直接写就好辣。
    时间复杂度O(nlogn),代码如下:
     1 #include <bits/stdc++.h>
     2 #define Maxn 1000007
     3 using namespace std;
     4 int read()
     5 {
     6     int x=0,f=1;char ch=getchar();
     7     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
     8     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     9     return x*f;
    10 }
    11 struct seg
    12 {
    13     int lx,rx;
    14     long long tag,mx;
    15 };
    16 int n,m;
    17 int f[Maxn],w[Maxn];
    18 int next[Maxn],last[Maxn];
    19 seg tree[Maxn*4];
    20 long long ans=0;
    21 void build(int node, int l, int r)
    22 {
    23     tree[node].lx=l,tree[node].rx=r;
    24     tree[node].tag=0,tree[node].mx=0;
    25     if (l==r) return;
    26     int mid=(l+r)/2;
    27     build(node*2,l,mid);
    28     build(node*2+1,mid+1,r);
    29 }
    30 void pushdown(int node)
    31 {
    32     if (tree[node].tag==0) return;
    33     tree[node*2].tag+=tree[node].tag;
    34     tree[node*2].mx+=tree[node].tag;
    35     tree[node*2+1].tag+=tree[node].tag;
    36     tree[node*2+1].mx+=tree[node].tag;
    37     tree[node].tag=0;
    38 }
    39 void update(int node, int l, int r, long long del)
    40 {
    41     if (tree[node].rx<l) return;
    42     if (tree[node].lx>r) return;
    43     if (tree[node].lx>=l&&tree[node].rx<=r)
    44     {
    45         tree[node].tag+=del;
    46         tree[node].mx+=del;
    47         return;
    48     }
    49     pushdown(node);
    50     update(node*2,l,r,del);
    51     update(node*2+1,l,r,del);
    52     tree[node].mx=max(tree[node*2].mx,tree[node*2+1].mx);
    53 }
    54 int main()
    55 {
    56     n=read(),m=read();
    57     memset(f,0,sizeof(f));
    58     for (int i=1;i<=n;i++)
    59         f[i]=read();
    60     memset(w,0,sizeof(w));
    61     for (int i=1;i<=m;i++)
    62         w[i]=read();
    63     memset(last,0,sizeof(last));
    64     for (int i=n;i;i--)
    65     {
    66         next[i]=last[f[i]];
    67         last[f[i]]=i;
    68     }
    69     build(1,1,n);
    70     for (int i=1;i<=m;i++)
    71         if (last[i])
    72         {
    73             if (next[last[i]]>0)
    74                 update(1,last[i],next[last[i]]-1,w[i]);
    75             else update(1,last[i],n,w[i]);
    76         }
    77     for (int i=1;i<=n;i++)
    78     {
    79         ans=max(ans,tree[1].mx);
    80         int pos=next[i];
    81         if (pos>0)
    82         {
    83             update(1,i,pos-1,-w[f[i]]);
    84             if (next[pos]>0)
    85                 update(1,pos,next[pos]-1,w[f[i]]);
    86             else update(1,pos,n,w[f[i]]);
    87         } else update(1,i,n,-w[f[i]]);
    88     }
    89     printf("%lld
    ",ans);
    90     return 0;
    91 }
  • 相关阅读:
    Go 语言机制之逃逸分析
    类型转换和类型断言
    浅析rune数据类型
    Go 文件操作(创建、打开、读、写)
    字符编码笔记:ASCII,Unicode 和 UTF-8
    cmd.exe启动参数详解
    linux下.so、.ko、.a的区别
    Python 和C#的交互
    Innodb表压缩过程中遇到的坑(innodb_file_format)
    更改mysql的加密方式和密码策略
  • 原文地址:https://www.cnblogs.com/Tommyr7/p/6993825.html
Copyright © 2011-2022 走看看