zoukankan      html  css  js  c++  java
  • bzoj 3747: [POI2015]Kinoman

    (颓废扒题解2333)

    给颜色的下一个出现位置记录一下,然后每次只有第一个颜色的出现位置和下一个出现位置之间会产生这种颜色的价值,所以用线段树维护一下区间。

    那么现在就只需要把整个的数列从1->n搞一下,然后移动左端点,每次都更新答案就好,每一次移动,当前位置和下一个出现本颜色的出现位置减去,下一个和下下个加上就好,(没下下个就n呗2333,,,都一样)

     1 #include<bits/stdc++.h>
     2 #define N 100005
     3 #define M 10000005
     4 #define LL long long
     5 #define inf 0x3f3f3f3f
     6 using namespace std;
     7 inline int ra()
     8 {
     9     int x=0,f=1; char ch=getchar();
    10     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    11     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    12     return x*f;
    13 }
    14 int n,m;int f[1000005],w[1000005];
    15 int last[1000005],next[1000005];
    16 LL ans;
    17 struct seg{    
    18     int l,r;    
    19     LL tag,mx;
    20 }t[4000005];
    21 void pushdown(int k)
    22 {
    23     int l=t[k].l,r=t[k].r;
    24     if (l==r) return;
    25     LL tag=t[k].tag; t[k].tag=0;
    26     t[k<<1].tag+=tag; t[k<<1|1].tag+=tag;
    27     t[k<<1].mx+=tag; t[k<<1|1].mx+=tag;
    28 }
    29 void build(int k, int l, int r)
    30 {
    31     t[k].l=l; t[k].r=r;
    32     if (l==r) return;
    33     int mid=l+r>>1;
    34     build(k<<1,l,mid); build(k<<1|1,mid+1,r);
    35 }
    36 void add(int k, int x, int y, int val)
    37 {
    38     if (t[k].tag) pushdown(k);
    39     int l=t[k].l,r=t[k].r;
    40     if (l==x && y==r)
    41     {
    42         t[k].tag+=val; t[k].mx+=val;
    43         return;
    44     }
    45     int mid=l+r>>1;
    46     if (y<=mid) add(k<<1,x,y,val);
    47     else if (x>mid) add(k<<1|1,x,y,val);
    48     else add(k<<1,x,mid,val),add(k<<1|1,mid+1,y,val);
    49     t[k].mx=max(t[k<<1].mx,t[k<<1|1].mx);
    50 }
    51 int main()
    52 {
    53     n=ra(); m=ra();
    54     for (int i=1; i<=n; i++) f[i]=ra();
    55     for (int i=1; i<=m; i++) w[i]=ra();
    56     for (int i=n; i>=1; i--) next[i]=last[f[i]],last[f[i]]=i;
    57     build(1,1,n);
    58     for (int i=1; i<=m; i++)
    59         if (last[i])
    60         {
    61             if (!next[last[i]]) add(1,last[i],n,w[i]);
    62             else add(1,last[i],next[last[i]]-1,w[i]);
    63         }
    64     for (int i=1; i<=n; i++)
    65     {
    66         ans=max(ans,t[1].mx);
    67         int t=next[i];
    68         if (t)
    69         {
    70             add(1,i,t-1,-w[f[i]]);
    71             if (next[t]) add(1,t,next[t]-1,w[f[i]]);
    72             else add(1,t,n,w[f[i]]);
    73         }
    74         else add(1,i,n,-w[f[i]]);
    75     }
    76     cout<<ans;
    77     return 0;
    78 }
  • 相关阅读:
    MYSQL索引
    MYSQL 外键 on语句 多表查询
    MYSQL用户管理
    MYSQL数据类型 表基本操作 表记录增删改 单表查询
    JQuery 引用方式
    JQuery 元素操作 each循环
    Android EditText方框验证码 短信验证码攻略
    android MVP模式介绍与实战
    一些不错的Android开源音视频播放器
    Android可伸缩布局-FlexboxLayout(支持RecyclerView集成)
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6426361.html
Copyright © 2011-2022 走看看