zoukankan      html  css  js  c++  java
  • 【bzoj5452】[Hnoi2016]大数(莫队)

      题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=4542

      首先若p=2,5则这题就是道傻逼题,前缀和搞一下没了。如果p为其他质数,那么可以这么处理:

      我们先预处理出数组num[i]表示原串第i~n位表示的数模p的余数,那么第l~r位表示的数模p的余数为(num[l]-num[r+1])/10^(n-r),因为10^(n-r)与p互质,所以若num[l]=num[r+1],则第l~r位表示的数是p的倍数。于是莫队一下就好了。

      代码:

    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<string>
    #include<iostream> 
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<map>
    #define ll long long
    #define ull unsigned long long
    #define max(a,b) (a>b?a:b)
    #define min(a,b) (a<b?a:b)
    #define lowbit(x) (x& -x)
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define eps 1e-18
    #define maxn 2000010
    inline ll read(){ll tmp=0; char c=getchar(),f=1; for(;c<'0'||'9'<c;c=getchar())if(c=='-')f=-1; for(;'0'<=c&&c<='9';c=getchar())tmp=(tmp<<3)+(tmp<<1)+c-'0'; return tmp*f;}
    inline ll power(ll a,ll b){ll ans=1; for(;b;b>>=1){if(b&1)ans=ans*a%mod; a=a*a%mod;} return ans;}
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline void swap(int &a,int &b){int tmp=a; a=b; b=tmp;}
    using namespace std;
    struct data{
        int l,r,id;
    }a[100010];
    struct data2{
        ll val;
        int id;
    }x[100010];
    char s[100010];
    ll rk[100010],cnt[100010],ans[100010],sum1[100010],sum2[100010];
    int n,m,size;
    ll p,tot;
    bool cmp(data a,data b){return a.l/size!=b.l/size?a.l/size<b.l/size:a.r<b.r;}
    bool cmp2(data2 a,data2 b){return a.val<b.val;}
    int main()
    {
        p=read();
        scanf("%s",s); n=strlen(s); size=sqrt(n);
        m=read();
        if(p==2||p==5){
            sum1[0]=sum2[0]=0;
            for(int i=1;i<=n;i++){
                sum1[i]=sum1[i-1]; sum2[i]=sum2[i-1];
                if((s[i-1]-'0')%p==0)++sum1[i],sum2[i]+=i;
            }
            for(int i=1;i<=m;i++){
                int l=read(),r=read();
                printf("%lld
    ",sum2[r]-sum2[l-1]-(sum1[r]-sum1[l-1])*(l-1));
            }
            fclose(stdin); fclose(stdout);
            return 0;
        }
        for(int i=1;i<=m;i++)
            a[i].l=read()-1,a[i].r=read(),a[i].id=i;
        sort(a+1,a+m+1,cmp);
        ll tmp=1; x[n].val=0; x[n].id=n;
        for(int i=n-1;i>=0;i--,tmp=tmp*10%p)x[i].val=(x[i+1].val+(s[i]-'0')*tmp)%p,x[i].id=i;
        sort(x,x+n+1,cmp2);
        rk[x[0].id]=0;
        for(int i=1;i<=n;i++)
            if(x[i].val==x[i-1].val)rk[x[i].id]=rk[x[i-1].id];
            else rk[x[i].id]=i;
        tot=0;
        for(int i=a[1].l;i<=a[1].r;i++)
            tot+=cnt[rk[i]]++;
        ans[a[1].id]=tot;
        for(int i=2;i<=m;i++){
            if(a[i-1].l<a[i].l){
                for(int j=a[i-1].l;j<a[i].l;j++)
                    tot-=--cnt[rk[j]];
            }
            else{
                for(int j=a[i].l;j<a[i-1].l;j++)
                    tot+=cnt[rk[j]]++;
            }
            if(a[i-1].r<a[i].r){
                for(int j=a[i-1].r+1;j<=a[i].r;j++)
                    tot+=cnt[rk[j]]++;
            }
            else{
                for(int j=a[i].r+1;j<=a[i-1].r;j++)
                    tot-=--cnt[rk[j]];
            }
            ans[a[i].id]=tot;
        }
        for(int i=1;i<=m;i++)
            printf("%lld
    ",ans[i]);
    }
    bzoj4542
  • 相关阅读:
    java异常
    集群、分布式、负载均衡区别
    基本数据结构的比较
    记录一次tomcat问题排查记录:org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 19
    记录 Java 的 BlockingQueue 中的一些坑
    Java高级面试题解析(二):百度Java面试题前200页(精选)
    学习netty遇到的关于 LineBasedFrameDecoder 的问题
    ThreadPoolExecutor 入参 corePoolSize 和 maximumPoolSize 的联系
    TreeMap 的排序冲突吗
    checkbox jquery操作总结
  • 原文地址:https://www.cnblogs.com/quzhizhou/p/9735726.html
Copyright © 2011-2022 走看看