学在线评测系统。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.