Problem:
Score : 400 points

Problem Statement

We have N+1 integers: 10^{100}, 10^{100}+1, ..., 10^{100}+N.

We will choose K or more of these integers. Find the number of possible values of the sum of the chosen numbers, modulo (10^9+7).

Constraints

1 \leq N \leq 2\times 10^5

1 \leq K \leq N+1

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N K

Output

Print the number of possible values of the sum, modulo (10^9+7).

Sample Input 1

3 2

Sample Output 1

10

The sum can take 10 values, as follows:

(10^{100})+(10^{100}+1)=2\times 10^{100}+1

(10^{100})+(10^{100}+2)=2\times 10^{100}+2

(10^{100})+(10^{100}+3)=(10^{100}+1)+(10^{100}+2)=2\times 10^{100}+3

(10^{100}+1)+(10^{100}+3)=2\times 10^{100}+4

(10^{100}+2)+(10^{100}+3)=2\times 10^{100}+5

(10^{100})+(10^{100}+1)+(10^{100}+2)=3\times 10^{100}+3

(10^{100})+(10^{100}+1)+(10^{100}+3)=3\times 10^{100}+4

(10^{100})+(10^{100}+2)+(10^{100}+3)=3\times 10^{100}+5

(10^{100}+1)+(10^{100}+2)+(10^{100}+3)=3\times 10^{100}+6

(10^{100})+(10^{100}+1)+(10^{100}+2)+(10^{100}+3)=4\times 10^{100}+6

Sample Input 2

200000 200001

Sample Output 2

1

We must choose all of the integers, so the sum can take just 1 value.

Sample Input 3

141421 35623

Sample Output 3

220280457

Solution in C++ (GCC 9.2.1) (judge verdict: Accepted)

#include<stdio.h>
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;


#define     LL                      long long int
#define     LD                      long double
#define     ULL                     unsigned long long int


#define     pii                     pair<int, int>
#define     mp                      make_pair
#define     pb                      push_back
#define     ff                      first
#define     ss                      second
#define     SZ(x)                   (int)x.size()
#define     all(x)                  x.begin(), x.end()
#define     lb(x, y)                lower_bound(all(x), y)
#define     rep(i, begin, end)      for (__typeof(end) i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))


#define     sp(x)                   setprecision(x) << fixed
#define     what_is(x)              cout << #x << " is " << x << endl


#define     PI                      acos(-1.0)
#define     EPS                     1e-12
#define     mx                      200010
#define     S_SIZE                  2000010


const LL inf = 1000000000;
const LL mod = 1000000000 + 7;


inline void IO() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); }
template<typename T> inline int dcmp (T x) { const T eps = EPS; return x < -eps ? -1 : (x > eps); }


template<class T> inline int CHECK(T MASK, int i) { return (MASK >> i) & 1; }
template<class T> inline T ON(T MASK, int i) { return MASK | (T(1) << i); }
template<class T> inline T OFF(T MASK, int i) { return MASK & (~(T(1) << i)); }
template<typename T> inline int CNT(T MASK) {
    if (numeric_limits<T>::digits <= numeric_limits<unsigned int>::digits) return __builtin_popcount(MASK);
    else return __builtin_popcountll(MASK);
}
template<class T> inline int RIGHT(T MASK) { return log2(MASK & -MASK); }


int dx4[] = { 0, 0, -1, +1 }; int dy4[] = { +1, -1, 0, 0 };
int dx8[] = { 1, 1, 0, -1, -1, -1, 0, 1, 0 }; int dy8[] = { 0, 1, 1, 1, 0, -1, -1, -1, 0 };


inline void I(int& a) { scanf("%d", &a); } inline void I(LL& a) { scanf("%lld", &a); }
inline void I(ULL& a) { scanf("%llu", &a); } inline void I(char* a) { scanf("%s", a); }
char Iarr[S_SIZE]; inline void I(string& a) { scanf("%s", Iarr); a = Iarr; }
inline void I(LD& a) { cin >> a; } inline void I(double& a) { cin >> a; }
inline void I(bool& a) { int aa; I(aa); a = aa; }
template<typename T1, typename T2>
void I(pair<T1, T2>& a) { I(a.ff); I(a.ss); }
template<typename T>
void I(vector<T>& a) { for (int i = 0; i < SZ(a); i++) I(a[i]); }
template<typename T, typename... Args>
void I(T& a, Args&... args) { I(a); I(args...); }


inline void OUT(int a) { printf("%d", a); } inline void OUT(LL a) { printf("%lld", a); }
inline void OUT(const char* a) { printf("%s", a); } inline void OUT(char* a) { printf("%s", a); }
inline void OUT(bool a) { printf("%d", a); } inline void OUT(string a) { rep(it, a.begin(), a.end()) printf("%c", *it); }
inline void OUT(ULL a) { printf("%llu", a); } inline void OUT(char a) { printf("%c", a); }
template<typename T, typename... Args>
void OUT(T a, Args... args) { OUT(a); OUT(" "); OUT(args...); }
template<typename... Args>
void O(Args... args) { OUT(args...); OUT("\n"); }


template<typename T1, typename T2>
inline ostream& operator<<(ostream& os, pair<T1, T2> p) { os << "{" << p.first << ", " << p.second << "}"; return os; }
template<typename T>
inline ostream& operator<<(ostream& os, vector<T>& a) { os << "["; for (int i = 0; i < (int)a.size(); i++) { if (i) os << ", "; os << a[i]; } os << "]"; return os; }


#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
	cout << *it << " = " << a << endl;
	err(++it, args...);
}


struct custom_hash {
    static uint64_t splitmix64(uint64_t x) { x += 0x9e3779b97f4a7c15; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; x = (x ^ (x >> 27)) * 0x94d049bb133111eb; return x ^ (x >> 31); }
    size_t operator()(uint64_t x) const { static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); return splitmix64(x + FIXED_RANDOM); }
};


void faster(auto &unorderedMap, int n) { int num = 2; while (num < n) num *= 2; unorderedMap.reserve(num); unorderedMap.max_load_factor(0.25); }

// gp_hash_table<LL, int, custom_hash> table;
// unordered_map<LL, int, custom_hash> table;
// head


const int M = 200010; // maximum number of cubes

LL tot[M];

int main()
{
//    int n = 4;
//    set<int> dp[n][n+1]; // considering (0...i), picking j elements distinct sums
//    for (int i = 0; i < n; i++) {
//        for (int j = 1; j <= i + 1; j++) {
//            if (j == 1) {
//                for (int k = 0; k <= i; k++) {
//                    dp[i][j].insert(k);
//                }
//            }
//            else {
//                if (i != 0) {
//                    for (int x : dp[i-1][j]) {
//                        dp[i][j].insert(x);
//                    }
//                    for (int x : dp[i-1][j-1]) {
//                        dp[i][j].insert(x + i);
//                    }
//                }
//            }
//        }
//    }
//    for (int i = 1; i <= n; i++) {
//        error(SZ(dp[n-1][i]));
//        int val = SZ(dp[n-1][i]);
//        set<int> temp = dp[n-1][i];
//        if (i != 1)
//        for (int x : dp[n-1][i-1]) {
//            temp.erase(x);
//        }
//        error(SZ(temp));
//        vector<int> v;
//        for (int x : dp[n-1][i]) {
//            v.pb(x);
//        }
//        error(v);
//    }
    int n, k;
    I(n, k);
    LL distinct = n + 1;
    LL inc;
//    LL tot[n+10];
    LL ans = 0;
//    for (int l = 1; l <= 100000; l++) {
//        n = l;
        for (int i = 1; i <= n + 1; i++) {
            if (i == 1) {
                tot[i] = n + 1;
                inc = n - 2;
            }
            else {
                tot[i] = tot[i-1] + inc;
                inc -= 2;
            }
            if (i >= k) {
                ans += tot[i];
            }
            else if (i > k) {
                ans += distinct;
            }
            if (tot[i] < 0) {
                error(i, tot[i], tot[i-1], inc);
            }
            ans %= mod;
            if (i == 1) distinct -= 2;
            else distinct--;
        }
//    }
    O(ans);

    return 0;
}