보급 그룹 순환
16594 단어 oi
순환 하 다.
알고리즘
(고밀도, 수학, 수론, 전달) O (10k 3) O (10k ^ 3) O (10k3)
인용 1: 전 k + 1 k + 1 k + 1 비트 의 모든 순환 절 길 이 는 반드시 전 k k k 비트 순환 절 길이 의 부분 집합 입 니 다.
증명:
4. 567917. 만약 에 앞의 k k k 비트 가 모두 다르다 면 앞의 k + 1 k + 1 k + 1 비트 도 반드시 다르다
인용 2: 최소 순환 절의 길이 가 t t t 라 고 가정 하면 모든 순환 절의 길 이 는 반드시 t t 의 정수 배 이다.
증명:
4.5567917. 순환 절 길이 r r r r 가 t t t 의 배수 가 아니 라 고 가정 하면 령 p = r m o d t p = r \ \, mod \, t p = rmodt, p < t p < t p < t, 그리고 임의의 정수 a a a 에 대해 서 는 모두 n a + n a + r − n a + r − t - t, n a + r − t - t, n a + r − t - 2 t.................. 2t..................................................................10 ^ k na..............................................................................................
따라서 우 리 는 어 릴 때 부터 한 명 씩 앞 k k k 비트 의 순환 절 길 이 를 내 놓 을 수 있다.
전 k 0 k 를 구 했다 고 가정 합 니 다.0 k0 비트 의 순환 절 길이 t 0 t0 t0, 그럼 우리 가 구하 기 전에 k 0 + 1 k0 + 1 k0 + 1 비트 의 순환 절 길 이 는 n 을 매 거 하기 만 하면 됩 니 다.× n t 0 , n × n 2 t 0 , n × n 3 t 0 , … , n × n 10 t 0 n×n^{t_0},n×n^{2t_0},n×n^{3t_0},…,n×n^{10t_0} n×nt0,n×n2t0,n×n3t0,…,n×n10t 0 이 n n n 과 같 으 면 됩 니 다.
앞 k 0 k0 k0 위 는 고정 불변 입 니 다. k 0 + 1 k 만 있 습 니 다.0 + 1 k0 + 1 비트 가 변 하기 때문에 최대 10 가지 선택 만 가능 합 니 다.
시간 복잡 도
모두 k k k 비트 를 전달 해 야 합 니 다. 매번 전달 할 때 최대 10 개 를 매 거 해 야 합 니 다. 매 거 할 때마다 높 은 정밀도 의 곱셈 을 사용 합 니 다.
여기 서 고밀도 곱셈 은 FFT 로 가속 하지 않 았 기 때문에 시간 복잡 도 는 O (10k 3) O (10k ^ 3) O (10k3) 입 니 다.
C + + 코드
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110;
int m;
int nums[N], power[N]; // power n^L_{k-1}
//
void mul(int c[], int a[], int b[])
{
static int temp[N];
memset(temp, 0, sizeof temp);
for (int i = 0; i < m; i++)
for (int j = 0; j < m; j++)
if (i + j < m)
temp[i + j] += a[i] * b[j];
for (int i = 0, t = 0; i < m; i++)
{
t += temp[i];
temp[i] = t % 10;
t /= 10;
}
memcpy(c, temp, sizeof temp);
}
//
void mul(int c[], int a[], int b)
{
for (int i = 0, t = 0; i < m; i++)
{
t += a[i] * b;
c[i] = t % 10;
t /= 10;
}
}
int main()
{
string str;
cin >> str >> m;
for (int i = 0, j = str.size() - 1; j >= 0; i++, j--)
nums[i] = str[j] - '0'; // nums
memcpy(power, nums, sizeof nums);
int per[N] = {1}; // per
int pn[N], p1[N];// pn n*n^iL_{k-1},p1 1*n^iL_{k-1}
for (int k = 1; k <= m; k++)
{
memcpy(pn, nums, sizeof pn); // n copy pn
memset(p1, 0, sizeof p1); // p1
p1[0] = 1;
//
int r = 0;
while (r <= 10)
{
mul(pn, pn, power); // pn = pn * power
mul(p1, p1, power); // p1 = p1 * power
r++;
if (pn[k - 1] == nums[k - 1])
break;
}
memcpy(power, p1, sizeof p1);
if (r > 10)
{
memset(per, 0, sizeof per);
per[0] = -1;
break;
}
mul(per, per, r); // per = per * r
}
int k = m;
while (!per[k])
k--; // 0
while (k >= 0)
cout << per[k--]; //
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
낙곡초보마을p10083연타P1008 3연타 제목 배경 본 문제는 답안 문제를 제출하는 것입니다. 당신은 프로그램을 쓰거나 계산기로 답을 계산한 후에 답안 텍스트를 직접 제출할 수도 있고 답안 생성 프로그램을 제출할 수도 있습니다. 제목 설명...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.