一、传送门

http://codeforces.com/contest/1029/problem/D

二、题意

给你$N$个数字$a_1,a_2,\cdots,a_n$,一个$K$,求所有$i \ne j$且$(a[i]*10^{len(a[j])}+a[j])%K=0$的pair的对数。

范围:$1 \le N \le 2*10^5$,$1 \le a[i] \le 10^9$,$1 \le K \le 10^9$。

三、思路

记录所有长度$i$,模$K$为$j$的数字的个数。用map记录,显然,键的种类不超过$2*10^5$。枚举map的所有键值对,假设键为$a$,解方程:$(a*10^x+b)%K=0(%K)$,当$x$已知时,$b=-a*10^x(%K)=(K-a*10^x)(%K)$。因为$1\le a[i] \le 10^9$,所以,$x$不超过$10$,可以枚举。然后已知$x$和$b$以后,作为键去map里面找出相应的值,和之前枚举的键值对的值相乘即可。

最后,因为有条件$i \ne j$,所以,再扫描一遍序列$a$,如果$(a[i]*10^{len(a[i])}+a[i])%K=0$,那么,答案减一。

但是,如果用pair<int, int>做map的键,上述思路的复杂度是$O(N*log(N)*log(N)*maxlen)$。这么大的复杂度我当时也想都没想就写了,我天,想什么呢。然后,我被Hack的TLE了。T_T。

那么,思路可以不变,把复杂度降一下就行了。把map的改为unordered_map,此时,键不能是pair,那就把记录个数的map改为$10$个unordered_map<int,long long>就行了。这样,需要枚举两层长度,再需要枚举长度为$i$下的unordered_map,总的复杂度变成了$O(N*maxlen*maxlen)$。那么,最差的ACM版复杂度就是$(N*10*10)$了,稳得很。

四、坑点

1、无论是map还是unordered_map,在迭代遍历的时候,千万不能通过方括号[]的方式去索引值。否则,如果键不存在,内置STL将会把键插进去,导致迭代次数和实际的size不相同。

2、预处理$10^i$,$i$最大是$10$,不是$9$。

3、最后扫描去掉$i=j$的情况时,因为$1 \le a[i] \le 10^9$,$10^{max\{len(a[i])\}}=10^10$,相乘等于$10^{19}$,大于long long的范围,会溢出,所以,一定要记得先把每一项$% K$,再相乘。否则,会挂在我代码最后面注释掉的那个样例。

五、代码(前面一大段都是没用的输入挂,有效代码在最后面)

#include<bits/stdc++.h>
using namespace std;
#define pb(x) push_back(x)
#define mk(x, y) make_pair(x, y)
#define pln() putchar('\n')
#define cln() (cout << '\n')
#define fi first
#define se second
#define MOD 1000000007LL
typedef long long LL;
typedef pair<int, int> PII;
;

/*********************************************************************/
namespace fastIO {
#define BUF_SIZE 100000
#define OUT_SIZE 100000
#define ll long long
//fread->read
    ;
    inline char nc() {
        static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
        if (p1 == pend) {
            p1 = buf; pend = buf + fread(buf, , BUF_SIZE, stdin);
            ; ;}
            //{printf("IO error!\n");system("pause");for (;;);exit(0);}
        }
        return *p1++;
    }
    inline bool blank(char ch) {return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';}
    inline void read(int &x) {
        ; ;
        for (; blank(ch); ch = nc());
        if (IOerror)return;
        , ch = nc();
         + ch - ';
        if (sign)x = -x;
    }
    inline void read(ll &x) {
        ; ;
        for (; blank(ch); ch = nc());
        if (IOerror)return;
        , ch = nc();
         + ch - ';
        if (sign)x = -x;
    }
    inline void read(double &x) {
        ; ;
        for (; blank(ch); ch = nc());
        if (IOerror)return;
        , ch = nc();
         + ch - ';
        if (ch == '.') {
            ; ch = nc();
            ');
        }
        if (sign)x = -x;
    }
    inline void read(char *s) {
        char ch = nc();
        for (; blank(ch); ch = nc());
        if (IOerror)return;
        for (; !blank(ch) && !IOerror; ch = nc()) * s++ = ch;
        *s = ;
    }
    inline void read(char &c) {
        for (c = nc(); blank(c); c = nc());
        ; return;}
    }
//getchar->read
    inline void read1(int &x) {
        ; x = ;
        ;
         + ch - ', ch = getchar());
        if (bo)x = -x;
    }
    inline void read1(ll &x) {
        ; x = ;
        ;
         + ch - ', ch = getchar());
        if (bo)x = -x;
    }
    inline void read1(double &x) {
        ; x = ;
        ;
         + ch - ', ch = getchar());
        if (ch == '.') {
            ;
            '), ch = getchar());
        }
        if (bo)x = -x;
    }
    inline void read1(char *s) {
        char ch = getchar();
        for (; blank(ch); ch = getchar());
        for (; !blank(ch); ch = getchar()) * s++ = ch;
        *s = ;
    }
    inline void read1(char &c) {for (c = getchar(); blank(c); c = getchar());}
//scanf->read
    inline void read2(int &x) {scanf("%d", &x);}
    inline void read2(ll &x) {
#ifdef _WIN32
        scanf("%I64d", &x);
#else
#ifdef __linux
        scanf("%lld", &x);
#else
        puts("error:can't recognize the system!");
#endif
#endif
    }
    inline void read2(double &x) {scanf("%lf", &x);}
    inline void read2(char *s) {scanf("%s", s);}
    inline void read2(char &c) {scanf(" %c", &c);}
    inline void readln2(char *s) {gets(s);}
//fwrite->write
    struct Ostream_fwrite {
        char *buf, *p1, *pend;
        Ostream_fwrite() {buf = new char[BUF_SIZE]; p1 = buf; pend = buf + BUF_SIZE;}
        void out(char ch) {
            if (p1 == pend) {
                fwrite(buf, , BUF_SIZE, stdout); p1 = buf;
            }
            *p1++ = ch;
        }
        void print(int x) {
            ], *s1; s1 = s;
            ';
            )out('-'), x = -x;
             + ;
            while(s1-- != s)out(*s1);
        }
        void println(int x) {
            ], *s1; s1 = s;
            ';
            )out('-'), x = -x;
             + ;
            while(s1-- != s)out(*s1); out('\n');
        }
        void print(ll x) {
            ], *s1; s1 = s;
            ';
            )out('-'), x = -x;
             + ;
            while(s1-- != s)out(*s1);
        }
        void println(ll x) {
            ], *s1; s1 = s;
            ';
            )out('-'), x = -x;
             + ;
            while(s1-- != s)out(*s1); out('\n');
        }
        void print(double x, int y) {
            , , , , , , , , ,
                               , 10000000000LL, 100000000000LL, 1000000000000LL, 10000000000000LL,
                               100000000000000LL, 1000000000000000LL, 10000000000000000LL, 100000000000000000LL
                              };
            )out('-'), x = -x; x *= mul[y];
            ll x1 = (ll)floor(x);
            if (x - floor(x) >= 0.5)++x1;
            ll x2 = x1 / mul[y], x3 = x1 - x2 * mul[y]; print(x2);
            ) {; i < y && x3 * mul[i] < mul[y]; '), ++i); print(x3);}
        }
        void println(double x, int y) {print(x, y); out('\n');}
        void print(char *s) {while (*s)out(*s++);}
        void println(char *s) {while (*s)out(*s++); out('\n');}
        , p1 - buf, stdout); p1 = buf;}}
        ~Ostream_fwrite() {flush();}
    } Ostream;
    inline void print(int x) {Ostream.print(x);}
    inline void println(int x) {Ostream.println(x);}
    inline void print(char x) {Ostream.out(x);}
    inline void println(char x) {Ostream.out(x); Ostream.out('\n');}
    inline void print(ll x) {Ostream.print(x);}
    inline void println(ll x) {Ostream.println(x);}
    inline void print(double x, int y) {Ostream.print(x, y);}
    inline void println(double x, int y) {Ostream.println(x, y);}
    inline void print(char *s) {Ostream.print(s);}
    inline void println(char *s) {Ostream.println(s);}
    inline void println() {Ostream.out('\n');}
    inline void flush() {Ostream.flush();}
//puts->write
    char Out[OUT_SIZE], *o = Out;
    inline void print1(int x) {
        ];
        char *p1 = buf;
        ';
        )*o++ = '-', x = -x;
         + ;
        while(p1-- != buf)*o++ = *p1;
    }
    inline void println1(int x) {print1(x); *o++ = '\n';}
    inline void print1(ll x) {
        ];
        char *p1 = buf;
        ';
        )*o++ = '-', x = -x;
         + ;
        while(p1-- != buf)*o++ = *p1;
    }
    inline void println1(ll x) {print1(x); *o++ = '\n';}
    inline void print1(char c) {*o++ = c;}
    inline void println1(char c) {*o++ = c; *o++ = '\n';}
    inline void print1(char *s) {while (*s)*o++ = *s++;}
    inline void println1(char *s) {print1(s); *o++ = '\n';}
    inline void println1() {*o++ = '\n';}
    inline ) == ; puts(Out);}}
    struct puts_write {
        ~puts_write() {flush1();}
    } _puts;
    inline void print2(int x) {printf("%d", x);}
    inline void println2(int x) {printf("%d\n", x);}
    inline void print2(char x) {printf("%c", x);}
    inline void println2(char x) {printf("%c\n", x);}
    inline void print2(ll x) {
#ifdef _WIN32
        printf("%I64d", x);
#else
#ifdef __linux
        printf("%lld", x);
#else
        puts("error:can't recognize the system!");
#endif
#endif
    }
    inline void println2(ll x) {print2(x); printf("\n");}
    inline void println2() {printf("\n");}
#undef ll
#undef OUT_SIZE
#undef BUF_SIZE
};
namespace slowIO {
    template <class T> inline void read(T &x) {
        int t;
        bool flag = false;
        ')) ;
        ';
         + t - ';
        if(flag) x = -x;
    }
};
/*********************************************************************/
/**$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$**/
/**$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$**/
/**$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$**/
/**$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$**/
/**$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$**/
/**$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$**/
/**$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$**/
/**$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$**/
/**$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$**/
/**$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$**/
/**$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$**/
/**$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$**/
/**$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$**/
/**$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$**/
/**$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$**/
/**$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$**/

using namespace fastIO;
//using namespace slowIO;
LL n, k, a[MAXN], p10[], len[MAXN];
typedef unordered_map<LL, LL> mp;
mp cnt[];

int calc(int x) {
    ;
    ) {
        res++;
        x /= ;
    }
    return res;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("d.in", "r", stdin);
#endif // ONLINE_JUDGE
    ;
    p10[] = ;
    ; i <= ; ++i)p10[i] = p10[i - ] * 10LL;
    read(n), read(k);
    ; i < n; ++i) {
        read(a[i]);
        len[i] = calc(a[i]);
        ml = max(ml, (int)len[i]);
        cnt[len[i]][a[i] % k]++;
    }
    LL ans = ;
    ; j <= ml; ++j) {
        for(auto e : cnt[j]) {
            LL A = e.fi;
            ; i <= ml; ++i) {
                LL B = ((k - A * (p10[i] % k)) % k + k) % k;
                B = (B + k) % k;
                mp::iterator it2 = cnt[i].find(B);
                if(it2 != cnt[i].end())ans += e.se * it2->se;
            }
        }
    }
    ; i < n; ++i) {
        LL t2 = (((a[i] % k) * (p10[len[i]] % k) % k) + a[i]) % k;
        )ans--;
    }
    cout << ans << endl;
    ;
}
/*
2 27961
1000000000 1000000000
*/

Codeforces Round #506 D. Concatenated Multiples题解的更多相关文章

  1. Codeforces Round #506 (Div. 3) 题解

    Codeforces Round #506 (Div. 3) 题目总链接:https://codeforces.com/contest/1029 A. Many Equal Substrings 题意 ...

  2. Codeforces Round #506 (Div. 3) D-F

    Codeforces Round #506 (Div. 3) (中等难度) 自己的做题速度大概只尝试了D题,不过TLE D. Concatenated Multiples 题意 数组a[],长度n,给 ...

  3. # Codeforces Round #529(Div.3)个人题解

    Codeforces Round #529(Div.3)个人题解 前言: 闲来无事补了前天的cf,想着最近刷题有点点怠惰,就直接一场cf一场cf的刷算了,以后的题解也都会以每场的形式写出来 A. Re ...

  4. Codeforces Round #557 (Div. 1) 简要题解

    Codeforces Round #557 (Div. 1) 简要题解 codeforces A. Hide and Seek 枚举起始位置\(a\),如果\(a\)未在序列中出现,则对答案有\(2\ ...

  5. Codeforces Round #506 (Div. 3) E

    Codeforces Round #506 (Div. 3) E dfs+贪心 #include<bits/stdc++.h> using namespace std; typedef l ...

  6. Codeforces Round #506 (Div. 3) D. Concatenated Multiples

    D. Concatenated Multiples You are given an array aa, consisting of nn positive integers. Let's call ...

  7. 【Codeforces Round】 #431 (Div. 2) 题解

    Codeforces Round #431 (Div. 2)  A. Odds and Ends time limit per test 1 second memory limit per test ...

  8. Codeforces Round #540 (Div. 3) 部分题解

    Codeforces Round #540 (Div. 3) 题目链接:https://codeforces.com/contest/1118 题目太多啦,解释题意都花很多时间...还有事情要做,就选 ...

  9. Codeforces Round #538 (Div. 2) (A-E题解)

    Codeforces Round #538 (Div. 2) 题目链接:https://codeforces.com/contest/1114 A. Got Any Grapes? 题意: 有三个人, ...

随机推荐

  1. Python mode_+

    f = open("葫芦小金刚", mode="r+", encoding="utf-8") content = f.read(2) # 顺 ...

  2. SWIFT Optional Value

    SWIFT中有一个类型定义叫可选值,在变量类型后面加一个?号即可定义一个类型为Optional Value的变量,当在使用变量时要用到强制解包!. 如在页面上有一个可选输入年龄的框,在接受数据的时间就 ...

  3. C语言基础:函数指针 分类: iOS学习 c语言基础 2015-06-10 21:55 15人阅读 评论(0) 收藏

    函数指针:指向函数的指针变量. 函数名相当于首地址. 函数指针定义:返回值类型  (*函数指针变量名)(参数类型1,参数类型2,....)=初始值 函数指针类型:返回值类型  (*)(参数类型1,参数 ...

  4. 单目标优化问题 常用的 测试函数(MATLAB版)

    ############################################### #                测试函数                     # ######## ...

  5. 20155216 2016-2017-2 《Java程序设计》第五周学习总结

    20155216 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 使用try,catch,finally处理异常 JVM会尝试执行try区块中的程序代码,如果 ...

  6. Struts2访问ServletAPI的三种方式

    web应用中需要访问的ServletAPI,通常只有HttpServletRequest,HttpSession,ServletContext三个,这三个接口分别代表jsp内置对象中的request, ...

  7. HDU 6188:Duizi and Shunzi(贪心)(广西邀请赛)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6188 题意 有n个数字,每个数字小于等于n,两个相同的数字价值为1,三个连续的数字价值为1 .问这n个 ...

  8. Alternative Thinking 找规律

    Kevin has just recevied his disappointing results on the USA Identification of Cows Olympiad (USAICO ...

  9. test20181005 迷宫

    题意 分析 时间复杂度里的n,m写反了. 出题人很有举一反三的精神. 代码 我的代码常数巨大,加了各种优化后开O3最慢点都要0.9s. #include<cstdlib> #include ...

  10. ZH奶酪:【Python】random模块

    Python中的random模块用于随机数生成,对几个random模块中的函数进行简单介绍.如下:random.random() 用于生成一个0到1的随机浮点数.如: import random ra ...