一、找出规律,每次只截取1的长度k次与直接截取k的长度它的价值是一样的。
二、利用差分统计一棵树的最高最矮的范围
三、统计结果,从最高的高度开始遍历
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#define ll long long
#define rep(i,a,n) for(int i = a; i <= n; i ++)
#define per(i,a,n) for(int i = n; i >= a; i --)
#define pb push_back
// #define IOS std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
//using namespace std;
const ll N = 1e6 + 10;
const ll inf = 998244353;
int x[N];
ll qmi(ll m, ll k, ll p){//快速幂
ll uu = 1 % p, t = m;
while (k)
{
if (k&1) uu = uu * t % p;
t = t * t % p;
k >>= 1;
}
return uu;
}
void solve(){
ll n,m;
std::cin >> n >> m;
std::vector<ll>op(N + 10);
ll rr = 0;//利用rr来找最高的数是多高,为下面循环的界限做限制,可以有效提高速度和没有必要的运算
rep(i,1,n){
ll a,b;
std::cin >> a >> b;
rr = std::max(rr,a);
op[a + 1] --;//运用了差分
op[b + 1] ++;//运用了差分,不能是b因为是最后的底线,相当于0,是不算在内的
}
rep(i,1,rr){//循环的限制不是很大
op[i] += op[i - 1];
}
ll res = 0;
per(i,1,rr){//循环的限制不是很大
if(m == 0) break;//没有空间了,没必要继续循环下去,节省一点时间(对于该题没有多大影响)
ll uu = std::min(m,op[i]);
m -= uu;
res = res + uu * (2 * i - 1);//最关键的公式,每次截取1
}
std::cout << res << "\n";
return;
}
int main(){
// IOS
solve();
return 0;
}