数轴上存在
这道题告诉我们,题做不出来的时候要多去去厕所,去溜达一圈之后或许就突然想明白了。。
我感觉还算是一道挺有意思的题,比较奇妙,难度适中,蓝色评的也很合理。
显然当
此时显然如果有
观察发现剩下的可能性就只有
此时的原式为
然后在
剩下的两个区间也同理推导一下即可:
现在我们也就能确定下来每一条
此时我们就需要考虑一下求
不难想到 map
存即可,排序也省了。
至此,我们就做完了这道奇怪的大分类讨论,复杂度
781
2
3
4
5
6
7
8
9
10
11using namespace std;
12using namespace __gnu_pbds;
13
14mt19937 rnd(random_device{}());
15int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
16bool rnddd(int x){return rndd(1, 100) <= x;}
17
18typedef unsigned int uint;
19typedef unsigned long long unll;
20typedef long long ll;
21typedef long double ld;
22
23template< typename T = int >
24inline T read(void);
25
26int N;
27ll origin(0);
28ll mn(LONG_LONG_MAX);
29map < ll, ll > mp;
30ll sum[310000]; int cnt(0);
31
32void Insert(int p, int v){
33 if(mp.find(p) == mp.end())mp.insert({p, v});
34 else mp[p] += v;
35}
36void InsertAll(int sp1, int sp2, int sp3){
37 Insert(sp1, -1);
38 Insert(sp2, 2);
39 Insert(sp3, -1);
40}
41
42int main(){
43 N = read();
44 for(int i = 1; i <= N; ++i){
45 int a = read(), b = read();
46 origin += abs(a - b);
47 if(0 <= 2 * a && 2 * a < b)InsertAll(2 * a, b, 2 * b - 2 * a);
48 else if(b < 2 * a && 2 * a <= 0)InsertAll(2 * b - 2 * a, b, 2 * a);
49 else if(a < 0 && 0 < b)InsertAll(0, b, 2 * b);
50 else if(b < 0 && 0 < a)InsertAll(2 * b, b, 0);
51 }
52 ll cur(0), sum(origin); int lft(INT_MIN);
53 mn = origin;
54 for(auto v : mp){
55 sum += (ll)cur * (v.first - lft);
56 cur += v.second, lft = v.first;
57 mn = min(mn, sum);
58 }
59 printf("%lld\n", mn);
60 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
61 return 0;
62}
63
64template < typename T >
65inline T read(void){
66 T ret(0);
67 short flag(1);
68 char c = getchar();
69 while(c != '-' && !isdigit(c))c = getchar();
70 if(c == '-')flag = -1, c = getchar();
71 while(isdigit(c)){
72 ret *= 10;
73 ret += int(c - '0');
74 c = getchar();
75 }
76 ret *= flag;
77 return ret;
78}
update-2022_11_07 初稿