QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#494942#9139. Prefix Divisible by Suffixucup-team987#AC ✓4504ms3852kbC++208.6kb2024-07-27 17:46:482024-07-27 17:46:49

Judging History

你现在查看的是最新测评结果

  • [2024-07-27 17:46:49]
  • 评测
  • 测评结果:AC
  • 用时:4504ms
  • 内存:3852kb
  • [2024-07-27 17:46:48]
  • 提交

answer

#include<iostream>
#include<algorithm>
#include<vector>
#include<cassert>

#include <algorithm>
#include <cassert>
#include <tuple>
#include <vector>


#include <utility>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

struct barrett {
    unsigned int _m;
    unsigned long long im;

    explicit barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    unsigned int umod() const { return _m; }

    unsigned int mul(unsigned int a, unsigned int b) const {

        unsigned long long z = a;
        z *= b;
#ifdef _MSC_VER
        unsigned long long x;
        _umul128(z, im, &x);
#else
        unsigned long long x =
            (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
        unsigned int v = (unsigned int)(z - x * _m);
        if (_m <= v) v += _m;
        return v;
    }
};

constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    constexpr long long bases[3] = {2, 7, 61};
    for (long long a : bases) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);

constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};

    long long s = b, t = a;
    long long m0 = 0, m1 = 1;

    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b


        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);

unsigned long long floor_sum_unsigned(unsigned long long n,
                                      unsigned long long m,
                                      unsigned long long a,
                                      unsigned long long b) {
    unsigned long long ans = 0;
    while (true) {
        if (a >= m) {
            ans += n * (n - 1) / 2 * (a / m);
            a %= m;
        }
        if (b >= m) {
            ans += n * (b / m);
            b %= m;
        }

        unsigned long long y_max = a * n + b;
        if (y_max < m) break;
        n = (unsigned long long)(y_max / m);
        b = (unsigned long long)(y_max % m);
        std::swap(m, a);
    }
    return ans;
}

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

long long pow_mod(long long x, long long n, int m) {
    assert(0 <= n && 1 <= m);
    if (m == 1) return 0;
    internal::barrett bt((unsigned int)(m));
    unsigned int r = 1, y = (unsigned int)(internal::safe_mod(x, m));
    while (n) {
        if (n & 1) r = bt.mul(r, y);
        y = bt.mul(y, y);
        n >>= 1;
    }
    return r;
}

long long inv_mod(long long x, long long m) {
    assert(1 <= m);
    auto z = internal::inv_gcd(x, m);
    assert(z.first == 1);
    return z.second;
}

std::pair<long long, long long> crt(const std::vector<long long>& r,
                                    const std::vector<long long>& m) {
    assert(r.size() == m.size());
    int n = int(r.size());
    long long r0 = 0, m0 = 1;
    for (int i = 0; i < n; i++) {
        assert(1 <= m[i]);
        long long r1 = internal::safe_mod(r[i], m[i]), m1 = m[i];
        if (m0 < m1) {
            std::swap(r0, r1);
            std::swap(m0, m1);
        }
        if (m0 % m1 == 0) {
            if (r0 % m1 != r1) return {0, 0};
            continue;
        }


        long long g, im;
        std::tie(g, im) = internal::inv_gcd(m0, m1);

        long long u1 = (m1 / g);
        if ((r1 - r0) % g) return {0, 0};

        long long x = (r1 - r0) / g % u1 * im % u1;

        r0 += x * m0;
        m0 *= u1;  // -> lcm(m0, m1)
        if (r0 < 0) r0 += m0;
    }
    return {r0, m0};
}

long long floor_sum(long long n, long long m, long long a, long long b) {
    assert(0 <= n && n < (1LL << 32));
    assert(1 <= m && m < (1LL << 32));
    unsigned long long ans = 0;
    if (a < 0) {
        unsigned long long a2 = internal::safe_mod(a, m);
        ans -= 1ULL * n * (n - 1) / 2 * ((a2 - a) / m);
        a = a2;
    }
    if (b < 0) {
        unsigned long long b2 = internal::safe_mod(b, m);
        ans -= 1ULL * n * ((b2 - b) / m);
        b = b2;
    }
    return ans + internal::floor_sum_unsigned(n, m, a, b);
}

}  // namespace atcoder

using namespace std;
template<typename T>
T extgcd(T a,T b,T&x,T&y)
{
	if(b==0)
	{
		x=1;
		y=0;
		return a;
	}
	T q=a/b;
	T g=extgcd(b,a-q*b,y,x);
	y-=q*x;
	return g;
}
long long N;
int c;
int keta(int v)
{
	assert(v>0);
	int k=0;
	while(v>0)v/=10,k++;
	return k;
}
long long gcd(long long a,long long b)
{
	while(b)
	{
		long long t=a%b;
		a=b;
		b=t;
	}
	return a;
}
long long p10[15];
bool OK[1<<17];
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	p10[0]=1;
	for(int i=1;i<15;i++)p10[i]=p10[i-1]*10;
	cin>>N>>c;
	long long ans=0;
	if(N==(long long)1e14)
	{
		if(((long long)1e13)%c==0)ans++;//n ok
		N--;
	}
	for(int s=0;s<=N;s++)
	{
		int sk=s==0?1:keta(s);
		long long n=(N-s)/p10[sk]/(s+c);
		if(n<=0)break;
		vector<pair<long long,long long> >del;
		for(int i=1;i<sk;i++)
		{
			if(i+1<sk&&s%p10[sk-i]==s%p10[sk-i-1])continue;
			//(s+c)*k*p10[sk]+s
			long long a=(s+c)*p10[i],b=s/p10[sk-i];//a*k+b
			long long m=s%p10[sk-i]+c;
			b=(m-b)%m;
			//a*k==b mod m
			long long x,y;
			long long g=extgcd(a,m,x,y);
			if(b%g!=0)
			{//none
			}
			else
			{
				a/=g;b/=g;m/=g;
				assert(a*x+m*y==1);
				//a*x+m*y==1
				//a*x==1 mod m
				//k==b*x mod m
				b=b*x%m;
				if(b<0)b+=m;
				del.push_back(make_pair(b,m));
				/*
				{
					long long na=(s+c)*p10[i],nb=s/p10[sk-i];//a*k+b
					long long nm=s%p10[sk-i]+c;
					for(long long k=1;k<=n;k++)
					{
						assert(((na*k+nb)%nm==0)==(k%m==b));
					}
				}
				*/
			}
		}
		if(n<=(1<<del.size())*200)
		{//O(del*n*|del)
			for(int k=1;k<=n;k++)OK[k]=true;
			for(auto p:del)
			{
				for(int k=p.first;k<=n;k+=p.second)OK[k]=false;
			}
			for(int k=1;k<=n;k++)ans+=OK[k];
		}
		else
		{//O(2**|del|*|del|)
			long long now=n;
			for(int i=1;i<1<<del.size();i++)
			{
				vector<long long>r,m;
				long long check=1;
				bool out=false;
				for(int j=0;j<del.size();j++)if(i>>j&1)
				{
					r.push_back(del[j].first),m.push_back(del[j].second);
					long long g=gcd(check,m.back());
					check/=g;
					if(m.back()>(long long)1e18/check)
					{
						out=true;
						break;
					}
					check*=m.back();
				}
				if(out)continue;
				pair<long long,long long>p=atcoder::crt(r,m);
				if(p.first==0)p.first+=p.second;
				if(p.second>0&&n>=p.first)
				{
					long long t=(n-p.first)/p.second+1;
					if(r.size()%2==1)now-=t;
					else now+=t;
				}
			}
			ans+=now;
		}
	}
	cout<<ans<<"\n";
}

这程序好像有点Bug,我给组数据试试?

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3548kb

input:

20 1

output:

2

result:

ok 1 number(s): "2"

Test #2:

score: 0
Accepted
time: 0ms
memory: 3536kb

input:

111 4

output:

9

result:

ok 1 number(s): "9"

Test #3:

score: 0
Accepted
time: 0ms
memory: 3616kb

input:

1111 10

output:

75

result:

ok 1 number(s): "75"

Test #4:

score: 0
Accepted
time: 1ms
memory: 3544kb

input:

1000000 7

output:

111529

result:

ok 1 number(s): "111529"

Test #5:

score: 0
Accepted
time: 0ms
memory: 3544kb

input:

1 1

output:

0

result:

ok 1 number(s): "0"

Test #6:

score: 0
Accepted
time: 0ms
memory: 3516kb

input:

99999 10000

output:

0

result:

ok 1 number(s): "0"

Test #7:

score: 0
Accepted
time: 0ms
memory: 3536kb

input:

1000 1

output:

287

result:

ok 1 number(s): "287"

Test #8:

score: 0
Accepted
time: 0ms
memory: 3524kb

input:

10000000 1

output:

3102010

result:

ok 1 number(s): "3102010"

Test #9:

score: 0
Accepted
time: 2ms
memory: 3488kb

input:

100000000 1

output:

31035571

result:

ok 1 number(s): "31035571"

Test #10:

score: 0
Accepted
time: 2ms
memory: 3824kb

input:

1000000000 1

output:

310375697

result:

ok 1 number(s): "310375697"

Test #11:

score: 0
Accepted
time: 20ms
memory: 3536kb

input:

10000000000 1

output:

3103907933

result:

ok 1 number(s): "3103907933"

Test #12:

score: 0
Accepted
time: 24ms
memory: 3600kb

input:

100000000000 1

output:

31039265058

result:

ok 1 number(s): "31039265058"

Test #13:

score: 0
Accepted
time: 275ms
memory: 3852kb

input:

1000000000000 1

output:

310394177863

result:

ok 1 number(s): "310394177863"

Test #14:

score: 0
Accepted
time: 328ms
memory: 3552kb

input:

10000000000000 1

output:

3103943538348

result:

ok 1 number(s): "3103943538348"

Test #15:

score: 0
Accepted
time: 3616ms
memory: 3552kb

input:

100000000000000 1

output:

31039449626535

result:

ok 1 number(s): "31039449626535"

Test #16:

score: 0
Accepted
time: 3726ms
memory: 3600kb

input:

100000000000000 10

output:

9041696367054

result:

ok 1 number(s): "9041696367054"

Test #17:

score: 0
Accepted
time: 3869ms
memory: 3536kb

input:

100000000000000 100

output:

1744469671929

result:

ok 1 number(s): "1744469671929"

Test #18:

score: 0
Accepted
time: 4134ms
memory: 3756kb

input:

100000000000000 1000

output:

263959224215

result:

ok 1 number(s): "263959224215"

Test #19:

score: 0
Accepted
time: 4504ms
memory: 3540kb

input:

100000000000000 10000

output:

35400402243

result:

ok 1 number(s): "35400402243"

Test #20:

score: 0
Accepted
time: 3963ms
memory: 3616kb

input:

100000000000000 239

output:

870346971377

result:

ok 1 number(s): "870346971377"

Test #21:

score: 0
Accepted
time: 3887ms
memory: 3604kb

input:

99999987654321 111

output:

1606282527743

result:

ok 1 number(s): "1606282527743"

Test #22:

score: 0
Accepted
time: 4346ms
memory: 3608kb

input:

96709210826727 9568

output:

35605797003

result:

ok 1 number(s): "35605797003"

Test #23:

score: 0
Accepted
time: 1005ms
memory: 3616kb

input:

22952388910151 8412

output:

9470863043

result:

ok 1 number(s): "9470863043"

Test #24:

score: 0
Accepted
time: 2129ms
memory: 3600kb

input:

49191272026279 3065

output:

49381052989

result:

ok 1 number(s): "49381052989"

Test #25:

score: 0
Accepted
time: 3416ms
memory: 3552kb

input:

75434450109703 9205

output:

28741533023

result:

ok 1 number(s): "28741533023"

Test #26:

score: 0
Accepted
time: 329ms
memory: 3824kb

input:

1677628193127 753

output:

5631822336

result:

ok 1 number(s): "5631822336"

Test #27:

score: 0
Accepted
time: 3ms
memory: 3532kb

input:

1000010000 10000

output:

328824

result:

ok 1 number(s): "328824"

Extra Test:

score: 0
Extra Test Passed