In a fast power matrix Lantern spree

Title Description

  Homework is music, a given positive integer N, M, required calculation Concatenate (1 ...... N) of the value of mod M, where 1 refers to Concatenate put together to obtain a number N. The N = 13, Concatenate = 12345678910111213

Input Format

  Row of two integers, N, M

Output Format

  A non-negative integer calculation result

Sample

Enter 1313

Output 4

data range

  n<=1018,m<=109

analysis

  At first glance this question: Analog violence

  Then see the data indicate silent, 1e18 ah, this is put together much big

  Regardless of the first to get a simulation:

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
unsigned long long s;
int n, m;
int wei(int x) {
    int s = 0;
    while (x) {
        s++;
        x /= 10;
    }
    return s;
}
int main () {
    freopen("le.in", "r", stdin);
    freopen("le.out", "w", stdout);
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
        s = (s * pow(10, wei(i)) + i),
        s = s % m;
    cout << s;
    return 0;
}

  This should be easy to understand, not explained, 30 points

  As a qualified OI players, must be considered positive solutions.

Set ans [i] represents the mosaic to answer when i bit, we can easily get recursive formula:

  ans[i]=(ans[i-1]*p+i)%mod; 

Wherein p i denotes the current number of bits by ten, MOD is not considered, such ans [4] = 123 * 10 + 4;

So this is a recursive problem, then how to do it? Violence run again? 1e18 data is not lost on me TLE

So this time matrix power quickly come ......

A is a matrix may be provided

  {Ans [i] i 1} I diet anyway open one-dimensional array. . . .

Then the other matrix K is

  {p 0 0}

  {1 1 0}

  {1 1 1}

Such A * K can be obtained {ans [i] * p + i i + 1 1} i.e. {ans [i + 1] i + 1 1}

Is not very clever, it is easy to see the action of the A 1 - and ans [i], Couchu ans [i + 1] and i + 1.

Then consider how much power problems multiply, we start from i = 0, if n = 4, then obviously have to take four times;

If n = 14 it? From 0 to 9, to take a total of nine times, and then by five times from 10 to 14

Then iterate many times difficult to find, we can use variable data copy n

If n> = p can take 9 * p / 10 times, data value by subtracting

When n <p by not described, so the data is directly multiplied times

Finally, run fast power on the line

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
ull n,mod,a[4],c[4][4];
void Mul(){
    wool cp [ 4 ];
    memset(cp,0,sizeof(cp));
    for(int i=1;i<=3;i++){
        for(int j=1;j<=3;j++){
            CP [I] + = ((A [J] mod%) * (C [J] [I] mod%))% mod;
             // before multiplication mod what otherwise must be the product of two numbers may be beyond longlongs 
            CP [I ]% = MOD;
        }  
    }
    memcpy(a,cp,sizeof(cp));
}
void Mulself () {
    wool cp [ 4 ] [ 4 ];
    memset(cp,0,sizeof(cp));
    for(int i=1;i<=3;i++)
        for(int j=1;j<=3;j++)
            for(int k=1;k<=3;k++){
                cp [i] [j] + = ((c [i] [k]% v) * (c [k] [j]% v))% v;
                cp [i] [j] % = v;
            }
    memcpy(c,cp,sizeof(cp));
}
int main () {
    scanf("%llu%llu",&n,&mod);
    a[1]=0;a[2]=0;a[3]=1;
    ull mx=n*10,data=n;
    for(ull p=10LL;p<=mx;p*=10LL){
        c[1][1]=p;c[1][2]=0;c[1][3]=0;
        c[2][1]=1;c[2][2]=1;c[2][3]=0;
        c[3][1]=1;c[3][2]=1;c[3][3]=1;
        ull x;
        if(n>=p){
            x=9LL*p/10LL;
            data-=x;
        }
        else x=data;
        while(x){
            if(x&1)Mul();
            x>>=1;
            Mulself ();
        }
    }
    printf("%llu\n",a[1]);
}

 

 

 

Guess you like

Origin www.cnblogs.com/anyixing-fly/p/12420244.html