Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 1dd79fe

Browse files
Final update before archiving
1 parent 90bb1dc commit 1dd79fe

File tree

1 file changed

+75
-76
lines changed

1 file changed

+75
-76
lines changed

‎DMOJ/apio10p1.cpp

Lines changed: 75 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,75 @@
1-
// Ivan Carvalho
2-
// Solution to https://dmoj.ca/problem/apio10p1
3-
#include <cstdio>
4-
#include <algorithm>
5-
#include <vector>
6-
using namespace std;
7-
typedef long long ll;
8-
vector<ll> M,B;
9-
int pointer;
10-
bool bad(int l1,int l2,int l3)
11-
{
12-
/*
13-
intersection(l1,l2) has x-coordinate (b1-b2)/(m2-m1)
14-
intersection(l1,l3) has x-coordinate (b1-b3)/(m3-m1)
15-
set the former greater than the latter, and cross-multiply to
16-
eliminate division
17-
*/
18-
return (B[l3]-B[l1])*(M[l1]-M[l2])<(B[l2]-B[l1])*(M[l1]-M[l3]);
19-
}
20-
//Adds a new line (with lowest slope) to the structure
21-
void add(long long m,long long b)
22-
{
23-
//First, let's add it to the end
24-
m *= -1;
25-
b *= -1;
26-
M.push_back(m);
27-
B.push_back(b);
28-
//If the penultimate is now made irrelevant between the antepenultimate
29-
//and the ultimate, remove it. Repeat as many times as necessary
30-
while (M.size()>=3&&bad(M.size()-3,M.size()-2,M.size()-1))
31-
{
32-
M.erase(M.end()-2);
33-
B.erase(B.end()-2);
34-
}
35-
}
36-
//Returns the minimum y-coordinate of any intersection between a given vertical
37-
//line and the lower envelope
38-
long long query(long long x)
39-
{
40-
//If we removed what was the best line for the previous query, then the
41-
//newly inserted line is now the best for that query
42-
if (pointer>=M.size())
43-
pointer=M.size()-1;
44-
//Any better line must be to the right, since query values are
45-
//non-decreasing
46-
while (pointer<M.size()-1&&
47-
M[pointer+1]*x+B[pointer+1]<M[pointer]*x+B[pointer])
48-
pointer++;
49-
return -(M[pointer]*x+B[pointer]);
50-
}
51-
int main(){
52-
int TC = 1;
53-
while(TC--){
54-
M.clear();
55-
B.clear();
56-
pointer = 0;
57-
int n;
58-
scanf("%d",&n);
59-
ll a,b,c;
60-
scanf("%lld %lld %lld",&a,&b,&c);
61-
add(0LL,0LL);
62-
ll davez, soma = 0;
63-
for(int i=1;i<n;i++){
64-
scanf("%lld",&davez);
65-
soma += davez;
66-
ll best = query(soma) + a*soma*soma + b*soma + c;
67-
add(-2*a*soma,best + a*soma*soma - b*soma);
68-
}
69-
scanf("%lld",&davez);
70-
soma += davez;
71-
ll best = query(soma) + a*soma*soma + b*soma + c;
72-
printf("%lld\n",best);
73-
}
74-
return 0;
75-
}n 0;
76-
}
1+
// Ivan Carvalho
2+
// Solution to https://dmoj.ca/problem/apio10p1
3+
#include <cstdio>
4+
#include <algorithm>
5+
#include <vector>
6+
using namespace std;
7+
typedef long long ll;
8+
vector<ll> M,B;
9+
int pointer;
10+
bool bad(int l1,int l2,int l3)
11+
{
12+
/*
13+
intersection(l1,l2) has x-coordinate (b1-b2)/(m2-m1)
14+
intersection(l1,l3) has x-coordinate (b1-b3)/(m3-m1)
15+
set the former greater than the latter, and cross-multiply to
16+
eliminate division
17+
*/
18+
return (B[l3]-B[l1])*(M[l1]-M[l2])<(B[l2]-B[l1])*(M[l1]-M[l3]);
19+
}
20+
//Adds a new line (with lowest slope) to the structure
21+
void add(long long m,long long b)
22+
{
23+
//First, let's add it to the end
24+
m *= -1;
25+
b *= -1;
26+
M.push_back(m);
27+
B.push_back(b);
28+
//If the penultimate is now made irrelevant between the antepenultimate
29+
//and the ultimate, remove it. Repeat as many times as necessary
30+
while (M.size()>=3&&bad(M.size()-3,M.size()-2,M.size()-1))
31+
{
32+
M.erase(M.end()-2);
33+
B.erase(B.end()-2);
34+
}
35+
}
36+
//Returns the minimum y-coordinate of any intersection between a given vertical
37+
//line and the lower envelope
38+
long long query(long long x)
39+
{
40+
//If we removed what was the best line for the previous query, then the
41+
//newly inserted line is now the best for that query
42+
if (pointer>=M.size())
43+
pointer=M.size()-1;
44+
//Any better line must be to the right, since query values are
45+
//non-decreasing
46+
while (pointer<M.size()-1&&
47+
M[pointer+1]*x+B[pointer+1]<M[pointer]*x+B[pointer])
48+
pointer++;
49+
return -(M[pointer]*x+B[pointer]);
50+
}
51+
int main(){
52+
int TC = 1;
53+
while(TC--){
54+
M.clear();
55+
B.clear();
56+
pointer = 0;
57+
int n;
58+
scanf("%d",&n);
59+
ll a,b,c;
60+
scanf("%lld %lld %lld",&a,&b,&c);
61+
add(0LL,0LL);
62+
ll davez, soma = 0;
63+
for(int i=1;i<n;i++){
64+
scanf("%lld",&davez);
65+
soma += davez;
66+
ll best = query(soma) + a*soma*soma + b*soma + c;
67+
add(-2*a*soma,best + a*soma*soma - b*soma);
68+
}
69+
scanf("%lld",&davez);
70+
soma += davez;
71+
ll best = query(soma) + a*soma*soma + b*soma + c;
72+
printf("%lld\n",best);
73+
}
74+
return 0;
75+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /