[Divisão e bloqueio]

T1: Portal de perguntas

Significado da pergunta T1 : defina f (n) como a soma dos fatores de n, forneça l e r, encontre f (l) + f (l + 1) +… + f (r)

Idéia: Primeiro, podemos definir g (n) como a soma do prefixo de f (n), então a equação a ser buscada é g (r) -g (l-1), para ag (n), podemos obter o equação g (n) = n / 1 * 1 + n / 2 * 2 + n / 3 * 3 +… + n / n * n, (O número de vezes que cada fator aparece é multiplicado pela contribuição do fator.)

Podemos dividir os fatores com o mesmo número de ocorrências em um bloco. Cada bloco tem um limite esquerdo e um limite direito. Podemos saber que o limite esquerdo do bloco atual é igual ao limite direito do bloco anterior + 1, e o limite direito é igual ao limite superior (n) / Os tempos do bloco atual, e os tempos do bloco atual é o limite superior (n) / limite esquerdo, ou seja, r = n / (n / r )

Finalmente, a soma da seqüência aritmética para cada bloco é suficiente.

Código:

#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: Portal da Pergunta

O significado da pergunta: forneça n, k, deixe você perguntar por k% 1 + k% 2 +… + k% n.

Idéia: Podemos discutir em duas situações.

Caso 1: n> = k, neste momento podemos transformar a fórmula em k% 1 + k% 2 +… + k% k + k * (nk), então, k% i = k -k / i * i , Assim, a fórmula é transformada em k * k- (k / 1 * 1 + k / 2 * 2 +… + k / k * k) + k * (nk) e, em seguida, pegue o tabuleiro diretamente.

Caso 2: n <k, ainda podemos levar a placa neste momento, mas no cálculo, quando a extremidade direita de um bloco ultrapassar n, deve ser definido como n, caso contrário, será contado mais. não é necessário considerar k * (nk) no primeiro caso.

Código:

#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;
}

Acho que você gosta

Origin blog.csdn.net/Joker_He/article/details/108848473
Recomendado
Clasificación