【计数 && 思维 && 数学】Codeforces Round #506 (Div. 3) D. Concatenated Multiples

Step1 Problem:

给你 n 个数 和 k,分别 a[1] … a[n].
connection(x, y) = xy.
connection(45, 112) = 45112.
让你求 connection(a[i], a[j])%k == 0 的个数 (i != j)
数据范围:
1 <= n <= 2e5, 2 <= k <= 1e9, 1 <= a[i] <= 1e9.

Step2 Ideas:

connection(45, 112) = 45112.
45112 = 45*1000+112;
(a[i]%k*mul%k + a[j]%k)%k == 0 // tmp 是 10 的倍数
我们可以枚举 a[i]%k, mul%k, 求有多少 a[j]%k 满足 == 0
a[j]%k = (k - (a[i]%k*mul%k)%k)%k;
时间复杂度 O(n*10*log(1e9));

Step3 Code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e5+5;
struct node
{
    int data, len;
};
node a[N];
map<int, int> has[15];
int main()
{
    int n, k;
    scanf("%d %d", &n, &k);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i].data);
        int t = a[i].data, num = 0;
        while(t) {
            num++;
            t = t / 10;
        }
        a[i].len = num;
        has[num][a[i].data%k]++;
    }
    ll ans = 0;
    for(int i = 1; i <= n; i++)//枚举 a[i]
    {
        ll mul = 1;
        has[a[i].len][a[i].data%k]--;
        for(int j = 1; j <= 10; j++)// 枚举 mul
        {
            mul *= 10; mul %= k;
            int tmp = k - ((a[i].data%k*mul)%k);
            if(has[j].count(tmp%k)) //少了这个 TLE
                ans += has[j][tmp%k];
        }
        has[a[i].len][a[i].data%k]++;
    }
    printf("%lld\n", ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值