[BZOJ3747] [POI2015]Kinoman

原创 2015年11月19日 18:46:07

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=3747

题目大意

给定一个序列,对于任意区间的价值为区间内只出现过一次的权值和,询问最大权值和

题解

我们定义点i后与点i相同的位置为next[i]
我们考虑每个点的贡献[i,next[i]1],所以我们最开始将所有第一次出现的种类覆盖的贡献范围加进线段树,然后从左向右枚举左端点,取最大值
取过最值后,这个点就不再贡献了,将[i,next[i]1]减掉它的贡献,再对[next[i],next[next[i]]1]next[i]
注意next[i]next[next[i]]值为0的情况
速度倒第二-_-

const
 maxn=1000005;
type
 nametype=record
 l,r:longint; val,tag:int64; end;
var
 w:array[0..4*maxn]of nametype;
 x,y,z,v,pre,next:array[0..maxn]of longint;
 i,j,k:longint;
 n,m:longint;
 tt,ans:int64;
function max(a,b:int64):int64;
begin
 if a>b then exit(a) else exit(b);
end;

procedure build(a,l,r:longint);
var mid:longint;
begin
 w[a].l:=l; w[a].r:=r; w[a].val:=0; w[a].tag:=0;
 if l=r then exit;
 mid:=(l+r)>>1;
 build(a<<1,l,mid); build(a<<1+1,mid+1,r);
end;

procedure pushdown(a:longint);
begin
 if w[a].l=w[a].r then begin w[a].tag:=0; exit; end;
 inc(w[a<<1].val,w[a].tag); inc(w[a<<1+1].val,w[a].tag);
 inc(w[a<<1].tag,w[a].tag); inc(w[a<<1+1].tag,w[a].tag);
 w[a].tag:=0;
end;

procedure update(a,l,r:longint;c:int64);
var mid:longint;
begin
 if l>r then exit;
 if w[a].tag<>0 then pushdown(a);
 if (l=w[a].l)and(r=w[a].r) then begin inc(w[a].val,c); inc(w[a].tag,c); exit; end;
 mid:=(w[a].l+w[a].r)>>1;
 if r<=mid then update(a<<1,l,r,c) else
 if l>mid then update(a<<1+1,l,r,c)
 else begin update(a<<1,l,mid,c); update(a<<1+1,mid+1,r,c); end;
 w[a].val:=max(w[a<<1].val,w[a<<1+1].val);
end;

function query(a,l,r:longint):int64;
var mid:longint;
begin
 if w[a].tag<>0 then pushdown(a);
 if (l=w[a].l)and(r=w[a].r) then exit(w[a].val);
 mid:=(w[a].l+w[a].r)>>1;
 if r<=mid then exit(query(a<<1,l,r)) else
 if l>mid then exit(query(a<<1+1,l,r))
 else exit(max(query(a<<1,l,mid),query(a<<1+1,mid+1,r)));
end;

begin
 readln(n,m);
 for i:=1 to n do
  begin
   read(y[i]);
   if pre[y[i]]=0 then v[i]:=1 else v[i]:=0;
   next[pre[y[i]]]:=i;
   pre[y[i]]:=i;
  end;
 for i:=1 to m do
  read(x[i]);
 build(1,1,n);
 for i:=1 to n do
  if v[i]=1
  then
   if next[i]=0
    then update(1,i,n,x[y[i]])
    else update(1,i,next[i]-1,x[y[i]]);
 ans:=0;
 for i:=1 to n do
  begin
   ans:=max(ans,query(1,i,n));
   if next[i]=0
   then update(1,i,n,-x[y[i]])
   else update(1,i,next[i]-1,-x[y[i]]);
   if next[i]<>0
   then
    if next[next[i]]=0
    then update(1,next[i],n,x[y[i]])
    else update(1,next[i],next[next[i]]-1,x[y[i]]);
  end;
 writeln(ans);
end.
版权声明:本文为博主原创文章,未经博主允许不得转载。

bzoj 3747: [POI2015]Kinoman

Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]。 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部。 你可以选择l,r(1 ...
  • lqybzx
  • lqybzx
  • 2015年06月21日 18:03
  • 353

BZOJ 3747: [POI2015]Kinoman 线段树

线段树 BZOJ POI2015

BZOJ 3747: [POI2015]Kinoman

线段树
  • Rlt1296
  • Rlt1296
  • 2016年11月28日 16:32
  • 147

【bzoj 3747】[POI2015]Kinoman(线段树)

一次等待,是生命的执守

BZOJ 3747 POI 2015 Kinoman 线段树

题目大意:给出电影院的放映电影顺序,一个电影只有看过一次的时候会获得电影的权值。没看过或者看两次或以上都不能获得权值。问看连续区间的电影能够获得的最大权值是多少。 思路:利用线段树维护前缀和...

BZOJ3747[POI2015] Kinoman

BZOJ[POI2015] Kinoman Description 共有mm部电影,编号为11~mm,第ii部电影的好看值为w[i]w[i]。 在nn天...
  • zqh_wz
  • zqh_wz
  • 2016年10月05日 22:08
  • 166

[POI2015] BZOJ 3747 看电影

传送门 题解: 有点类似于扫描线的思想还是第一次见,感觉非常秒。 考虑移动左端点,欲通过一些奇技淫巧计算最优右端点。 首先左端点在1。考虑对于某一种电影,这种电影的第一次出现的位置记为h,下一...
  • Mys_C_K
  • Mys_C_K
  • 2017年07月15日 17:43
  • 127

bzoj 4380: [POI2015]Myjnie 动态规划

感谢Claris的题解。        令t[l][r][x]表示l~r家店,最小的价格为x时,对于所有l=x的最大收入,同时令pos[l][r][x]表示最小的价格的店。然后就是O(N^3M)了。 ...

BZOJ4382: [POI2015]Podział naszyjnika

题目大意:把一个长度为n的一串项链切两刀,把项链断成两条链。要求每种颜色的珠子只能出现在其中一条链中。求方案数量以及切成的两段长度之差绝对值的最小值。 挺神的一道题,首先我们可以随便画一个项链玩一...
  • commonc
  • commonc
  • 2016年05月10日 08:25
  • 1217

BZOJ4381 POI2015 Odwiedziny

BZOJ4381 POI2015 Odwiedziny
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[BZOJ3747] [POI2015]Kinoman
举报原因:
原因补充:

(最多只允许输入30个字)