点击跳转例题
思路:最开始想用前缀和,但是暴力只能过掉30%。所以我们优化,对于每个数的前缀和,我们可以二分出,有多少个(高斯求和)类型的式子,然后加上剩下的数。对于二分出的高斯求和式子,我们可以预处理
#include <bits/stdc++.h> #define int long long //(有超时风险) #define PII pair<int,int> #define endl '\n' #define LL __int128 using namespace std; const int N=2e6+10,M=1e3+10,mod=998244353,INF=0x3f3f3f3f; //a为高斯求和式子。//b为a的前缀和,二分出来的求和式子要用 int a[N],b[N]; void prv() { a[1]=1;b[1]=1; //因为sqrt(1e12*2)<2e6;或者直接写。 for(int i=2;i<=2e6;i++) { a[i]=a[i-1]+i; b[i]=b[i-1]+a[i]; } } int pre(int x) { //二分出出多少个高斯求和式子。 int l=0,r=sqrt(x*2)+1; while(l<r) { int mid=(l+r+1)/2; if(mid*(mid+1)/2<=x)l=mid; else r=mid-1; } //tmp为剩下的长度。 int tmp=x-r*(r+1)/2; int ans=a[tmp]; ans+=b[r]; return ans; } signed main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); prv(); int n;cin>>n; while(n--) { int l,r;cin>>l>>r; cout<<pre(r)-pre(l-1)<<endl; } return 0; }
P8762 [蓝桥杯 2021 国 ABC] 123--二分+数学
最新推荐文章于 2024-05-17 09:49:17 发布