• 【BZOJ 3747】 3747: [POI2015]Kinoman (线段树)


    3747: [POI2015]Kinoman

    Time Limit: 60 Sec  Memory Limit: 128 MB
    Submit: 830  Solved: 338

    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。

    HINT

    Source

    【分析】

      这题应该挺经典。?

      就是先弄一个next,然后每次求以i结尾的最大值。

      i的值为w,next[i]的值为-w,更前面的next的值为0,线段树维护这个,(好像树状数组也是可以的),然后就好了。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 #define Maxn 1000010
     8 #define LL long long
     9 
    10 // int mymax(int x,int y) {return x>y?x:y;}
    11 LL mymax(LL x,LL y) {return x>y?x:y;}
    12 
    13 int a[Maxn],w[Maxn],f[Maxn],ft[Maxn],nt[Maxn];
    14 
    15 struct node
    16 {
    17     int l,r,lc,rc;
    18     LL mx,lazy;
    19 }tr[Maxn*2];
    20 
    21 int tot=0;
    22 int build(int l,int r)
    23 {
    24     int x=++tot;
    25     tr[x].l=l;tr[x].r=r;
    26     tr[x].lazy=tr[x].mx=0;
    27     if(l<r)
    28     {
    29         int mid=(l+r)>>1;
    30         tr[x].lc=build(l,mid);
    31         tr[x].rc=build(mid+1,r);
    32     }
    33     else tr[x].lc=tr[x].rc=0;
    34     return x;
    35 }
    36 
    37 void upd(int x)
    38 {
    39     tr[x].mx+=tr[x].lazy;
    40     if(tr[x].lazy==0||tr[x].l==tr[x].r) {tr[x].lazy=0;return;}
    41     int lc=tr[x].lc,rc=tr[x].rc;
    42     tr[lc].lazy+=tr[x].lazy;
    43     tr[rc].lazy+=tr[x].lazy;
    44     tr[x].lazy=0;
    45 }
    46 
    47 void change(int x,int l,int r,int y)
    48 {
    49     if(tr[x].l==l&&tr[x].r==r)
    50     {
    51         tr[x].lazy+=y;
    52         upd(x);
    53         return;
    54     }
    55     upd(x);
    56     int mid=(tr[x].l+tr[x].r)>>1;
    57     if(r<=mid) change(tr[x].lc,l,r,y);
    58     else if(l>mid) change(tr[x].rc,l,r,y);
    59     else
    60     {
    61         change(tr[x].lc,l,mid,y);
    62         change(tr[x].rc,mid+1,r,y);
    63     }
    64     upd(tr[x].lc);upd(tr[x].rc);
    65     tr[x].mx=mymax(tr[tr[x].lc].mx,tr[tr[x].rc].mx);
    66 }
    67 
    68 int main()
    69 {
    70     int n,m;
    71     scanf("%d%d",&n,&m);
    72     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    73     for(int i=1;i<=m;i++) scanf("%d",&w[i]);
    74     memset(ft,0,sizeof(ft));
    75     for(int i=1;i<=n;i++)
    76     {
    77         nt[i]=ft[a[i]];
    78         ft[a[i]]=i;
    79     }
    80     build(1,n);
    81     LL maxx=0;
    82     for(int i=1;i<=n;i++)
    83     {
    84         change(1,1,i,w[a[i]]);
    85         if(nt[i]) change(1,1,nt[i],-2*w[a[i]]);
    86         if(nt[nt[i]]) change(1,1,nt[nt[i]],w[a[i]]);
    87         maxx=mymax(maxx,tr[1].mx);
    88     }
    89     printf("%lld
    ",maxx);
    90     return 0;
    91 }
    View Code

    2017-04-08 10:54:12

  • 相关阅读:
    Object Modeling
    数据库的比较
    关系数据库与非关系数据库
    结构化查询语言-SQL
    SQLite
    acid (数据库事务正确执行的四个基本要素的缩写)
    UITableView设计思想 考察
    复杂软件的考虑点与UITableView
    设计模式与哲学
    复杂对象的组装与创建-建造者模式
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6681147.html
Copyright © 2020-2023  润新知