2020提高组模拟赛3 T1 白井黑子

\(\text{Problem}\)[2020提高组模拟赛3]白井黑子

\(\text{Solution}\)

发现物品是无序的,可以每加入一个数,就求它和前面的数能产生多少贡献,然后记入答案。对于本题,发现利用容斥原理,可以将答案转换为求出 \(f(a_{i})\times f(a_{j})\) 能被某个自然数的 \(k\) 次幂表示的 \((i,j)\) 对数,

\(K=0\) 时,\(f(a_{i})\) 不能为 \(0\),则对于 \(K=0\)\(K\not=0\) 的情况分开讨论。

对于 \(K=0\)\(x^{0}(x\not=0)\) 的值为 \(1\),所以只用记录有多少 \(f(a_{i})\) 的值为 \(1\) 即可。

对于 \(K\not=0\),发现当 \(f(a_{i})=0\) 时,它对答案产生了 \(i-1\) 的贡献。并且,如果目前已经出现过 \(g\)\(f(a_{i})=0\),则当 \(f(a_{i})\not=0\) 时,还要多产生 \(g\) 的贡献。当 \(f(a_{i})\not=0\) 时,它的质因数个数最多只有四个,分别为 \(2,3,5,7\)。所以考虑对于 \(f(a_{i})\) 进行质因数分解。记四元组 \((p1,p2,p3,p4)\) 表示 \(f(a_{i})=2^{p1}\times 3^{p2}\times 5^{p3}\times 7^{p4}\) ,则要找到对应的四元组 \((q1,q2,q3,q4)\),使得 \(p1+q1\equiv 0 \pmod K\)\(p2+q2\equiv 0 \pmod K\)\(p3+q3\equiv 0 \pmod K\)\(p4+q4\equiv 0 \pmod K\)。这个东西用桶或者 \(\text{map}\) 即可实现。

\(\text{Code}\)

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <bitset>
#define ri register
#define inf 0x7fffffff
#define E (1)
#define mk make_pair
#define int long long
//#define double long double
using namespace std; const int N=200010;
inline int read()
{
    int s=0, w=1; ri char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') w=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+(ch-'0'), ch=getchar();
    return s*w;
}
void print(int x) { if(x<0) x=-x, putchar('-'); if(x>9) print(x/10); putchar(x%10+'0'); }
int n,K,res,a[N],b[N],gg;
struct Node{int p1,p2,p3,p4; }e[N];
map<pair<pair<int,int>, pair<int,int> >,int> Q;
inline void SpecialD()
{
    for(ri int i=1;i<=n;i++)
    {
        int x=read();
        int qwq=1;
        while(x)
        {
            if(x%10!=1) qwq=0;
            x/=10;
        }
        res+=qwq;
    }
    printf("%lld\n",(n*(n-1)-res*(res-1))/2);
}
signed main()
{
    n=read(), K=read();
    if(!K) { SpecialD(); return 0; }
    for(ri int i=1;i<=n;i++)
    {
        a[i]=read();
        int k=a[i];
        int qwq=1;
        while(k)
        {
            int tt=k%10;
            if(!tt) break;
            qwq*=tt;
            k/=10;
        }
        if(k) { res+=i-1; gg++; continue; }
        int x=qwq;
        while(x%2==0) e[i].p1++, x/=2;
        x=qwq;
        while(x%3==0) e[i].p2++, x/=3;
        x=qwq;
        while(x%5==0) e[i].p3++, x/=5;
        x=qwq;
        while(x%7==0) e[i].p4++, x/=7;
        int q1=(K-e[i].p1)%K;
        int q2=(K-e[i].p2)%K;
        int q3=(K-e[i].p3)%K;
        int q4=(K-e[i].p4)%K;
        q1=(q1+K)%K, q2=(q2+K)%K, q3=(q3+K)%K, q4=(q4+K)%K;
        res+=Q[mk(mk(q1,q2),mk(q3,q4))];
        res+=gg;
        e[i].p1%=K, e[i].p2%=K, e[i].p3%=K, e[i].p4%=K;
        Q[mk(mk(e[i].p1,e[i].p2),mk(e[i].p3,e[i].p4))]++;
    }
    printf("%lld\n",n*(n-1)/2-res);
    return 0;
}
posted @ 2020-08-16 17:49  zkdxl  阅读(56)  评论(0编辑  收藏  举报