Universidad del Petróleo de China ACM club abierto juego de entrenamiento --- pregunta K: problemas matemáticos (+ prefijo y pretratamiento de dos dimensiones)

Pregunta K: problemas de matemáticas

Plazo: 1 Sec Límite de memoria: 128 MB
presentar: 381 Resolución: 24
[ Estado ] [ enviar ] [hombre proposición: Importación externo]

título Descripción

Hemos aprendido lo que la escuela secundaria es el número de combinaciones. Por lo tanto, dado un entero n, m, g, inteligente puede usted encontrar la cantidad de pares de números enteros (i, j), se reúnen g divisibles que? (En la que 0≤i≤n, 0≤j≤min (i, m) ). (Consejo: n = 1 x 2 x ⋯ × n; . En particular, 0 = 1 !!)

entrada

Una primera línea de número entero T (T <= 104), indica el número de conjuntos de datos de prueba;
segunda fila un número entero g (1 <g <= 25 );
los próximos dos números enteros cada línea de fila T n, m (n, m <= 2,000);
significado n, m, g ver Descripción tema.

 

exportación

líneas de salida T, cada uno un entero que representa el número de pares de números enteros (i, j) satisface divisible por g (0≤i≤n, 0≤j≤min (i, m )).

de entrada de muestra Copia

1 
4 
5 4

Un ejemplo de salida de copia

2

Un prefijo y s bidimensional [i] [j] = s [i-1] [j] + s [i] [j-1] -s [i-1] [j-1], el (n, m ) dentro de un rango predeterminado de un número entero de pares de la mesa de juego, el optimizador de consulta para cada O (1).

Pits: n posible <m

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int N = 2e3 + 10;

ll a[N][N];
ll sum[N][N];
ll g;

void init()
{
    memset(a, 0, sizeof(a));
    a[0][0] = 1;
    for(int i = 1; i < N; ++i)
    {
        a[i][0] = 1;
        a[i][i] = 1;
        for(int j = 1; j < i; ++j)
        {
            a[i][j] = ((a[i - 1][j] % g) + (a[i - 1][j - 1] % g)) % g;
        }
    }
}

void solve()
{
    memset(sum, 0, sizeof(sum));
    for(int i = 1; i < N; ++i)
    {
        for(int j = 1; j <= i; ++j)
        {
            sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
            if(a[i][j] == 0)
            {
                sum[i][j]++;
            }
        }
        sum[i][i + 1] = sum[i][i];
    }
}

int main()
{
    int n, t, m;
    while(~scanf("%d", &t))
    {
        scanf("%lld", &g);
        init();
        solve();
        while(t--)
        {
            scanf("%d%d", &n, &m);
            if(n < m)
                m = n;
            cout<<sum[n][m]<<'\n';
        }
    }
    return 0;
}

 

Ha publicado 188 artículos originales · ganado elogios 13 · vistas 10000 +

Supongo que te gusta

Origin blog.csdn.net/weixin_43871207/article/details/104747838
Recomendado
Clasificación