P3582 [POI2015] KIN segment tree

  

Title Description

A total of m films, numbered 1 ~ m, the i-th unit of the movies is nice w [i]. Among the n days (from No. 1 ~ n) will show a movie per day, day i screenings are f [i] section. You can choose l, r (1 <= l <= r <= n), and watch all the movies of l, l + 1, ..., r days. If you watch the same movie more than once, you will feel bored, so can not get the film look good value. So you want to maximize watch and watch only through the value of the sum of good-looking movie once.

Input Format

The first line of two integers n, m (1 <= m <= n <= 1000000). The second line contains n integers F [. 1], F [2], ..., F n . The third line contains integers m W [. 1], W [2], ..., W m .

Output Format

And viewing through viewing only output once the maximum value of the sum of the attractive film.

Sample input and output

Input # 1
9 4
2 3 1 1 4 1 2 4 1
5 3 6 6
Output # 1
15

Description / Tips

A total of m films, numbered 1 ~ m, the i-th unit of the movies is nice w [i].

Among the n days (from No. 1 ~ n) will show a movie per day, day i screenings are f [i] section.

You can choose l, r (1 <= l <= r <= n), and watch all the movies of l, l + 1, ..., r days. If you watch the same movie more than once, you will feel bored, so can not get the film look good value. So you want to maximize watch and watch only through the value of the sum of good-looking movie once.

 

 

There are two types of writing:

https://www.luogu.org/problemnew/solution/P3582

 

 

Seeking to ensure the maximum consecutive sub-segments of the same number most only one of the two front of a w -w

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define ll long long
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
const int N=2e6+10;

ll t[N<<2],lmax[N<<2],rmax[N<<2],sum[N<<2];

void up(int pos)
{
    sum[pos]=sum[pos<<1]+sum[pos<<1|1];
    lmax[pos]=max(lmax[pos<<1],sum[pos<<1]+lmax[pos<<1|1]);
    rmax[pos]=max(rmax[pos<<1|1],sum[pos<<1|1]+rmax[pos<<1]);
    t[pos]=max(max(t[pos<<1],t[pos<<1|1]),rmax[pos<<1]+lmax[pos<<1|1]);
}
void upnode(int x,int v,int l,int r,int pos)
{
    if(l==r){sum[pos]=lmax[pos]=rmax[pos]=t[pos]=1ll*v;return;}
    int m=(l+r)>>1;
    if(x<=m)upnode(x,v,l,m,pos<<1);
    else upnode(x,v,m+1,r,pos<<1|1);
    up(pos);
}
int n,m,w[N],f[N],fi[N],se[N];

int main()
{
    scanf("%d%d",&n,&m);
    rep(i,1,n)scanf("%d",&f[i]);
    rep(i,1,m)scanf("%d",&w[i]);
    ll ans=0;
    rep(i,1,n)
    {   
        if(!fi[f[i]])fi[f[i]]=i,upnode(i,w[f[i]],1,n,1);
        else if(!se[f[i]])se[f[i]]=i,upnode(fi[f[i]],-w[f[i]],1,n,1),upnode(i,w[f[i]],1,n,1);
        else upnode(fi[f[i]],0,1,n,1),upnode(se[f[i]],-w[f[i]],1,n,1),upnode(i,w[f[i]],1,n,1),fi[f[i]]=se[f[i]],se[f[i]]=i;
        ans=max(ans,t[1]);
    }
    cout<<ans;
    return 0;
}
View Code

 

 

 

Guess you like

Origin www.cnblogs.com/bxd123/p/11419207.html