数轴上存在
这道题告诉我们,题做不出来的时候要多去去厕所,去溜达一圈之后或许就突然想明白了。。
我感觉还算是一道挺有意思的题,比较奇妙,难度适中,蓝色评的也很合理。
显然当
此时显然如果有

观察发现剩下的可能性就只有
此时的原式为
然后在
剩下的两个区间也同理推导一下即可:
现在我们也就能确定下来每一条

此时我们就需要考虑一下求
不难想到 map 存即可,排序也省了。
至此,我们就做完了这道奇怪的大分类讨论,复杂度
78123
45678910
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 初稿