[Division and block]

T1: Question Portal

T1 question meaning : Define f(n) as the factor sum of n, give you l and r, find f (l) + f (l + 1) +… + f (r)

Idea: First, we can define g(n) as the prefix sum of f(n), then the equation to be sought is g(r)-g(l-1), for a g(n), we can get the equation g(n) = n / 1 * 1 + n / 2 * 2 + n / 3 * 3 + …+n / n *n, (The number of times each factor appears is multiplied by the factor contribution.)

We can divide the factors with the same number of occurrences into one block. Each block has a left boundary and a right boundary. We can know that the left boundary of the current block is equal to the right boundary of the previous block + 1, and the right boundary is equal to the upper limit (n )/The times of the current block, and the times of the current block is the upper limit (n)/left boundary, that is, r=n/(n/r).

Finally, the arithmetic sequence summation for each block is enough.

Code:

#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define endl '\n'
#define null NULL
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
#define int long long
#define pii pair<int,int>
#define ull unsigned long long
#define pdd pair<double,double>
#define lowbit(x) x&-x
#define all(x) x.begin(),x.end()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read()
{
    
    
    int x=0,f=1;
    char ch=gc();
    while(ch<'0'||ch>'9')
    {
    
    
        if(ch=='-')
            f=-1;
        ch=gc();
    }
    while(ch>='0'&&ch<='9')
    {
    
    
        x=x*10+ch-'0';
        ch=gc();
    }
    return x*f;
}
using namespace std;
const int N=3e5+1000;
const int inf=0x3f3f3f3f;
const int mod=998244353;
const double eps=1e-6;
const double PI=acos(-1);

ull solve(ull n)
{
    
    
    ull sum=0,l,r;
    for(l=1;l<=n;l=r+1)
    {
    
    
        r=n/(n/l);
        sum+=(n/l)*(r-l+1)*(r+l)/2;
    }
    return sum;
}
signed main()
{
    
    
	ull l,r;
	cin>>l>>r;
	cout<<solve(r)-solve(l-1)<<endl;
}

T2: Question Portal

The meaning of the question: give you n, k, let you ask for k%1+k%2+… +k%n.

Idea: We can discuss in two situations.

Case 1: n>=k, at this time we can transform the formula into k%1+k%2 +… +k%k +k * (nk), then, k%i = k -k / i * i , So the formula is transformed into k * k-(k / 1 * 1 + k / 2 * 2 +… + k / k * k) + k * (nk), and then directly take the board.

Case 2: n<k, we can still take the board at this time, but in the calculation, when the right end of a block exceeds n, it must be set to n, otherwise it will be counted more. Similarly, we will not Need to consider k*(nk) in the first case.

Code:

#include<bits/stdc++.h>
#define endl '\n'
#define null NULL
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
#define int long long
#define pii pair<int,int>
#define ull unsigned long long
#define pdd pair<double,double>
#define lowbit(x) x&-x
#define all(x) x.begin(),x.end()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read()
{
    
    
    int x=0,f=1;
    char ch=gc();
    while(ch<'0'||ch>'9')
    {
    
    
        if(ch=='-')
            f=-1;
        ch=gc();
    }
    while(ch>='0'&&ch<='9')
    {
    
    
        x=x*10+ch-'0';
        ch=gc();
    }
    return x*f;
}
using namespace std;
const int N=3e5+1000;
const int inf=0x3f3f3f3f;
const int mod=998244353;
const double eps=1e-6;
const double PI=acos(-1);

ull solve(ull n,ull k)
{
    
    
    ull sum=0,l,r;
    for(l=1;l<=k;l=r+1)
    {
    
    
        r=k/(k/l);
        if(r>n)
            r=n;
        sum+=(l+r)*(r-l+1)*(k/l)/2;
        if(r==n)
            break;
    }
    return sum;
}
signed main()
{
    
    
    ull n,k;
    cin>>n>>k;
    if(n>k)
        cout<<k*k-solve(n,k)+k*(n-k)<<endl;
    else
        cout<<n*k-solve(n,k)<<endl;
}

Guess you like

Origin blog.csdn.net/Joker_He/article/details/108848473