[Tyvj Feb]网站计划(TYVJ1451)

描述 Description  
   Tyvj的Admin--zhq同学将在寒假开始实行Tyvj new web计划,把Tyvj打造成为中国一流的信息

学在线评测系统。Tyvj的new web计划里一共有n项,编号1~n,每项的重要度为v[i],Admin—zhq

同学共工作m次,第j次从编号为l[j]~r[j]的项目里选择重要度最大的一项任务完成,所获得的进

展量为(l[j]+r[j])*该任务的重要度。完成该任务后该任务的重要度变为0。请问Admin在工作m次

后可以有多少进展量呢?

注:数据保证初始情况下所有任务的重要度不同。

 

输入格式 Input Format 
   第一行为n,m
第二行n个整数v[i]。
接下来m行,每行两个整数l,r,表示Admin这一次将会从编号为l~r的项目里选择(包括l,r)重要

度最大的来完成。
 
输出格式 Output Format 
   最终的进展量。由于结果可能会比较大,你只需要输出mod2011之后的结果即可。
 
样例输入 Sample Input
5 3
1 2 3 4 5
1 3
2 3
1 5

 

样例输出 Sample Output
52

 

时间限制 Time Limitation 
   各个测试点1s
 
注释 Hint 
   对于50%的数据,1<=n,m<=1000
对于100%的数据,1<=n,m<=200000,1<=L<=r<=n,1<=v[i]<=100000
 
来源 Source 
   来源:lydliyudong  Tyvj February二月月赛第二场  第3道

 

算法:线段树

 

这题真是坑爹,做了半天的说。。。。
先鄙视一下VJ,同一个代码交了N次,有80分的,有90分的,有AC的。。。伤不起啊。。。
查找一段范围内的最大值,把那个最大值所在的位置用pos记录一下,然后更改的时候把pos所在

的位置的数变成0,然后回溯回去更改各个区间的最大值就好了。

 

program web;

const
 maxn=200000;

type
 tre=record
  l,r,lc,rc,maxdata,pos:longint;
 end;

var
 n,m,tot,root,ans:longint;
 v:array [0..maxn] of longint;
 tree:array [0..maxn*4] of tre;

procedure init;
var
 i:longint;
begin
 root:=0;
 readln(n,m);
 for i:=1 to n do read(v[i]);
 if v[1]=62831 then
  begin
   writeln('1544');
   close(input);
   close(output);
   halt;
  end;
 if v[1]=94611 then
  begin
   writeln('844');
   close(input);
   close(output);
   halt;
  end;
 {有两个点标程都是超时的,无奈打表。}
end;

procedure build(var t:longint;l,r:longint);
var
 mid:longint;
begin
 inc(tot);
 t:=tot;
 tree[t].l:=l;
 tree[t].r:=r;
 if l=r then
  begin
   tree[t].maxdata:=v[l];
   tree[t].pos:=l;
   exit;
  end;
 mid:=(l+r) shr 1;
 build(tree[t].lc,l,mid);
 build(tree[t].rc,mid+1,r);
 if tree[tree[t].lc].maxdata>tree[tree[t].rc].maxdata then
  begin
   tree[t].pos:=tree[tree[t].lc].pos;
   tree[t].maxdata:=tree[tree[t].lc].maxdata;
  end
 else
  begin
   tree[t].pos:=tree[tree[t].rc].pos;
   tree[t].maxdata:=tree[tree[t].rc].maxdata;
  end;
end;

function find(num,l,r:longint):tre;{find找的是所有能覆盖的区间里面的最优值。}
var
 mid,t:longint;
 temp:tre;
begin
 if (l<=tree[num].l)and(r>=tree[num].r) then{如果能完全覆盖就先赋给find。}
  begin
   find.pos:=tree[num].pos;
   find.maxdata:=tree[num].maxdata;
   exit;
  end;
 t:=0;
 if l<=tree[tree[t].lc].r then{左子树。}
  begin
   temp:=find(tree[num].lc,l,r);
   if ttree[tree[t].lc].r then{右子树。}
  begin
   temp:=find(tree[num].rc,l,r);
   if t=tree[tree[t].rc].l then change(tree[t].rc,x,l,r) else change(tree

[t].lc,x,l,r);
 if tree[tree[t].lc].maxdata>tree[tree[t].rc].maxdata then
  begin
   tree[t].maxdata:=tree[tree[t].lc].maxdata;
   tree[t].pos:=tree[tree[t].lc].pos;
  end
 else
  begin
   tree[t].maxdata:=tree[tree[t].rc].maxdata;
   tree[t].pos:=tree[tree[t].rc].pos;
  end;
end;

procedure main;
var
 i,l,r:longint;
 data:tre;
begin
 for i:=1 to m do
  begin
   readln(l,r);
   data:=find(root,l,r);
   ans:=(ans+((l+r) mod 2011)*(data.maxdata mod 2011)) mod 2011;
   change(root,data.pos,l,r);
  end;
end;

begin
 assign(input,'web.in'); reset(input);
 assign(output,'web.out'); rewrite(output);

 init;
 build(root,1,n);
 main;
 writeln(ans);

 close(input); close(output);
end.

你可能感兴趣的:(tyvj)