题:https://ac.nowcoder.com/acm/contest/3979/C
题意:给定一个函数g(n,k),指的是n个点的图,每个点可染k种颜色中的一种,只有不同颜色之间才可以进行连边,求能达到的最大连边数。题目要求的是Σg(n,i)
分析:考虑单单的一个点k,考虑答案:C2n-p(总体-不满足=答案),而p函数显然就是相同颜色之间可连的边的数目,为了答案尽可能大,我们要让p函数尽可能小,即让相同颜色的点数的个数尽可能接近;
具体地就是n%k种颜色染了n/k个点,k-n%k种颜色染了n/k+1个点。
此时g(n,k)=C2n-(n%k)*Cx+12-(k-n%k)*Cx2 (其中x=n/k)
将n%k==n-n/k*k带入得g(n,k)=n2-n-2nx+k(x2+x)
而求和就考虑用分块解决(因为有x=n/k)

#include<bits/stdc++.h> using namespace std; typedef long long ll; #define pb push_back const int inf=0x3f3f3f3f; const ll INF=1e18; const int M=5e4+4; const int mod=998244353; ll ksm(ll a,ll b){ ll t=1; while(b){ if(b&1) t=(t*a)%mod; a=(a*a)%mod; b>>=1; } return t; } ll solve(ll x,ll y,ll n){ ll ans=0; ll l=x,r; while(l<=y){ /// cout<<l<<endl; r=n/(n/l); if(r>y) r=y; ll t=n/l; ans+=(n*n%mod-n-2*n%mod*t)%mod*(r-l+1)%mod; ans%=mod; ///等差求和/// ans+=(((t*t%mod+t)%mod)*((r+l)*(r-l+1)/2)%mod)%mod; ans%=mod; l=r+1; } return ans; } int main(){ int t; scanf("%d",&t); ll inv=ksm(2ll,mod-2); while(t--){ ll l,r,n; scanf("%lld%lld%lld",&n,&l,&r); ll ans=solve(l,r,n); ans=(ans+mod)%mod; ans*=inv; printf("%lld ",ans%mod); } return 0; }