HDU - 5936 Difference 2016 杭州 CCPC 思维题

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn=1e5+10;
struct nod
{
    int x,k;int i;
    bool operator <(const nod&a)const
    {
        return k<a.k;
    }
} q[101];
LL x,k;
LL a[10][10];
vector<int>mp;
LL f(LL y)
{
    LL r=0;
    while(y)
    {
        r+=a[y%10][k];
        y/=10;
    }
    return r;
}
int fx[maxn];
int cnt(LL x)
{
    if(x<mp.front()||x>mp.back())return 0;
    int a=lower_bound(mp.begin(),mp.end(),x)-mp.begin();
    int b=upper_bound(mp.begin(),mp.end(),x)-mp.begin();
    return b-a;
}
void init()
{
    for(int i=1;i<10;i++)
        for(int j=0;j<10;j++)
            a[i][j]= (j==0? 1:a[i][j-1]*i);
}
LL ans[101];
int main()
{
    #ifdef shuaishuai
    freopen("in.txt","r",stdin);
    #endif //  shuaishuai
    int t;
    scanf("%d",&t);
    q[0].k=0;
    for(int i=1;i<=t;i++)
    {
        scanf("%d%d",&q[i].x,&q[i].k);q[i].i=i;
    }
    sort(q,q+t); 
    init();
    LL mx=0,mi=0,mx2=0,mi2=0; //首先要能想出来这个数不超过10位 后面的就好想了
    for(int cas=1;cas<=t;cas++) // f(y1)-1e5*y1+f(y2)-y2=x 
    {
        x=q[cas].x,k=q[cas].k;
        LL r=0;
        if(q[cas].k!=q[cas-1].k){
            mp.clear();
            for(int i=0;i<100000;i++)
            {
                LL t=f(i); //会发现f([1,1e5],[1,9]) >=0且<=int_max
                fx[i]=t; 
                assert(t-i<=INT_MAX&&t-i>=INT_MIN); 
                mp.push_back(t-i);
            }
            sort(mp.begin(),mp.end());
        }
        for(int i=0;i<100000;i++)
        {
            LL t=x+100000LL*i-fx[i];
            if(t<=INT_MAX&&t>=INT_MIN) //如果用unordermap注意要先find 不然会加入结点然后爆炸
            r+=cnt(t);
        }
        ans[q[cas].i]=r-(x==0);
    }
    for(int i=1;i<=t;i++)
    {
        printf("Case #%d: %lld\n",i,ans[i]);
    } 
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/polya/p/9792398.html
今日推荐