• UVa11610 Reverse Prime


    题目大意

    定义了一种叫做Reverse Prime的数:位数为7位,倒转之后是六位的素数

    要求按顺序找出所有的Reverse Prime,并计算出每个Reverse Prime的因子数

    可以对这些数进行一下两种操作:

    1、“q i”查询区间[0,i]Reverse Prime的因子数之和

    2、“d reverse_prime”把reverse_prime这个Reverse Prime从序列中删除

    题解

    先把所有的Reverse Prime求出来,我们可以用筛选法求出所以六位的素数,然后进行倒置,然后在末位加一个0,这样就是Reverse Prime了,之后求出每个Reverse Prime的因子数,并对这些Reverse Prime进行升序排序,最后对这些数进行离散化。我们用两个树状数组来进行维护,一个树状数组用来记录位置0到位置i有多少个Reverse Prime,另外一个树状数组用来维护因子数和。对于第一个操作,用二分查找当前序列第i个Reverse Prime的位置,然后求因子数的前缀和,对于第二个操作,由于对Reverse Prime进行离散化了,可以直接找到这个Reverse Prime所在的位置,然后把这个位置上的Reverse Prime值置为0即可,非常好的题,挺综合的

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define MAXN 1000000
    using namespace std;
    typedef struct
    {
        int b;
        int pr;
    } NODE;
    NODE  s[MAXN+5];
    int a[MAXN+5],q1[MAXN+5],q2[MAXN+5],f[MAXN+5];
    int ans;
    int id[MAXN*10+5];
    int lowbit(int x)
    {
        return x&-x;
    }
    int sum(int *c,int x)
    {
        int ret=0;
        while(x>0)
        {
            ret+=c[x];
            x-=lowbit(x);
        }
        return ret;
    }
    void add(int *c,int x,int d)
    {
        while(x<=ans)
        {
            c[x]+=d;
            x+=lowbit(x);
        }
    }
    void prime()
    {
        long long  i,j;
        ans=0;
        memset(a,0,sizeof(a));
        memset(f,0,sizeof(f));
        for(i=2; i<=MAXN; i++)
            if(!f[i])
            {
                a[++ans]=i;
                for(j=i*i; j<=MAXN; j+=i)
                    if(!f[j]) f[j]=i;
            }
    }
    void fac(int i,int sum)
    {
        while(sum%2==0)
        {
            s[i].pr++;
            sum/=2;
        }
        while(f[sum])
        {
            s[i].pr++;
            sum/=f[sum];
        }
        if(sum!=1) s[i].pr++;
    }
    void deal(int x,int p)
    {
        int sum=0;
        while(x)
        {
            sum=sum*10+x%10;
            x/=10;
        }
        while(sum<1000000)
            sum*=10;
        s[p].pr=2;
        fac(p,sum/10);
        s[p].b=sum;
    }
    void solve()
    {
        int i;
        for(i=1; i<=ans; i++)
            deal(a[i],i);
    }
    bool cmp(NODE x,NODE y)
    {
        return x.b<y.b;
    }
    int main(void)
    {
        //freopen("prime.txt","r",stdin);
        //freopen("prime.out","w",stdout);
        char ch[5];
        int i,t,l,r,m;
        memset(s,0,sizeof(s));
        memset(q1,0,sizeof(q1));
        memset(q2,0,sizeof(q2));
        prime();
        solve();
        sort(s+1,s+ans+1,cmp);
        for(i=1; i<=ans; i++)
            add(q2,i,s[i].pr);
        for(i=1; i<=ans; i++)
        {
            id[s[i].b]=i;
            add(q1,i,1);
        }
        while(scanf("%s",ch)!=EOF)
        {
            scanf("%d",&i);
            if(ch[0]=='q')
            {
                ++i;
                l=1;
                r=ans;
                while(l<=r)
                {
                    m=(l+r)>>1;
                    t=sum(q1,m);
                    if(t==i) break;
                    if(t>i)
                        r=m-1;
                    else
                        l=m+1;
                }
                printf("%d\n",sum(q2,m));
            }
            else
            {
                t=id[i];
                add(q1,t,-1);
                add(q2,t,-s[t].pr);
            }
        }
        return 0;
    }
  • 相关阅读:
    POJ3709 K-Anonymous Sequence 斜率优化DP
    POJ3233 Matrix Power Series
    第六周 Leetcode 446. Arithmetic Slices II
    POJ1743 Musical Theme 最长重复子串 利用后缀数组
    Ural 1517. Freedom of Choice 后缀数组
    iOS跳转到另一个程序
    上传源码到github
    NSTimer用法,暂停,继续,初始化
    iOS中多线程原理与runloop介绍
    NSRunLoop 概述和原理
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3054528.html
Copyright © 2020-2023  润新知