首页 > 代码库 > 【BZOJ4868】期末考试(整数三分)

【BZOJ4868】期末考试(整数三分)

题意:

有n位同学,每位同学都参加了全部的m门课程的期末考试,都在焦急的等待成绩的公布。第i位同学希望在第ti天
或之前得知所.有.课程的成绩。如果在第ti天,有至少一门课程的成绩没有公布,他就会等待最后公布成绩的课程
公布成绩,每等待一天就会产生C不愉快度。对于第i门课程,按照原本的计划,会在第bi天公布成绩。有如下两种
操作可以调整公布成绩的时间:1.将负责课程X的部分老师调整到课程Y,调整之后公布课程X成绩的时间推迟一天
,公布课程Y成绩的时间提前一天;每次操作产生A不愉快度。2.增加一部分老师负责学科Z,这将导致学科Z的出成
绩时间提前一天;每次操作产生B不愉快度。上面两种操作中的参数X,Y,Z均可任意指定,每种操作均可以执行多次
,每次执行时都可以重新指定参数。现在希望你通过合理的操作,使得最后总的不愉快度之和最小
1<=N,M,Ti,Bi<=100000,0<=A,B<=100000,c<=10^16
 
思路:显然一堆线性函数之和一定是一个线性函数,整数三分即可 O(n log 1.5 n)
O(n)做法:
技术分享

 

 1 const oo=1<<60;
 2 var b,t:array[1..200000]of longint;
 3     n,m,i,l,r,mid,mid1,mid2:longint;
 4     a1,b1,c1,ans,s1,s2:int64;
 5 
 6 function max(x,y:longint):longint;
 7 begin
 8  if x>y then exit(x);
 9  exit(y);
10 end;
11 
12 function min(x,y:int64):int64;
13 begin
14  if x<y then exit(x);
15  exit(y);
16 end;
17 
18 function clac(x:longint):int64;
19 var i:longint;
20     s,tmp:int64;
21 begin
22  clac:=0;
23  for i:=1 to n do
24   if t[i]<x then
25   begin
26    if x-t[i]>(oo-clac) div c1 then exit(oo);
27    clac:=clac+c1*(x-t[i]);
28   end;
29 
30 
31  s:=0;
32  for i:=1 to m do
33   if b[i]<x then s:=s+x-b[i];
34  for i:=1 to m do
35   if b[i]>x then
36   begin
37    tmp:=b[i]-x;
38    if a1<b1 then
39    begin
40     if s>=tmp then
41     begin
42      clac:=clac+a1*tmp;
43      s:=s-tmp;
44     end
45      else
46      begin
47       clac:=clac+a1*s+b1*(tmp-s);
48       s:=0;
49      end;
50    end
51     else clac:=clac+b1*tmp;
52   end;
53 
54 end;
55 
56 begin
57  assign(input,bzoj4868.in); reset(input);
58  assign(output,bzoj4868.out); rewrite(output);
59  readln(a1,b1,c1);
60  readln(n,m);
61  r:=1;
62  for i:=1 to n do
63  begin
64   read(t[i]);
65   r:=max(r,t[i]);
66  end;
67  for i:=1 to m do
68  begin
69   read(b[i]);
70   r:=max(r,b[i]);
71  end;
72  l:=1; ans:=1<<60;
73  while l<=r do
74  begin
75   mid:=(l+r)>>1;
76   mid1:=(l+mid)>>1; mid2:=(mid+1+r)>>1;
77   s1:=clac(mid1); s2:=clac(mid2);
78   ans:=min(ans,s1); ans:=min(ans,s2);
79   if s1<=s2 then r:=mid2-1
80    else l:=mid1+1;
81  end;
82  writeln(ans);
83 
84  close(input);
85  close(output);
86 end.

 

 

【BZOJ4868】期末考试(整数三分)