参考代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll temp[1500000], sum[1500000]; //temp数组记录序号和,sum数组记录前缀和 ll cal(ll n) //计算自然数求和
{return (n+1)*n/2;
}int main()
{ios::sync_with_stdio(false); ll index = 1;ll endL;while(1) //打表法 {temp[index] = temp[index-1] + index;sum[index] = sum[index-1] + temp[index];if(temp[index] > 1e12) //当序号和大于上限时退出 {endL = index; //记录序号和退出时的下标,便于二分查找确立边界 break; }index++;}ll T;cin >> T;ll l, r, res;for(ll i = 0; i < T; i++){cin >> l >> r;ll leftL = lower_bound(temp, temp+endL, l) - temp; //lower_bound二分法查找 ll rightL = lower_bound(temp, temp+endL, r) - temp;res = sum[rightL-1] - sum[leftL-1]; //首先得到两个大段差 res -= cal(l-temp[leftL-1]-1); //其次减去左边界到上个大段结束点之间的前缀和 res += cal(r-temp[rightL-1]); //最后加上右边界到上个大段结束点之间的前缀和 cout << res << endl;}return 0;
}