zoukankan      html  css  js  c++  java
  • HDU 4913 Least common multiple(2014 Multi-University Training Contest 5)

    题意:求所有自己的最小公倍数的和。 该集合是  2^ai  * 3^bi

    思路:线段树。 线段树中存的是  【3^b * f(b)】   f(b)表示 因子3 的最小公倍数3的部分  为 3^b的个数  那么从小到大枚举a  对于当前的  ab  ,  如果之前的b小于当前的b  那么最小公倍数就为  (2^a) *  (3^b)   个数 就为 2^x     x表示a  b 都小于当前a b的个数 。  大于的部分 就直接是  2^a   * 线段树上【b,max】的和。   求好当前更新进去,对于 【b,max】 区间 直接乘2 (表示当前这个b可选可不选) 。       b位置加上(2^x)  * (3^b) 的值即可(当前b被选为最大的b时的个数)。

    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include <iostream>
    #define lson i<<1
    #define rson i<<1|1
    #define LL long long
    #define N 100050
    #define MOD 1000000007
    using namespace std;
    int cnt[N*4],val[N*4],sum[N*4],mul[N*4];
    int mypow(int a,int b)
    {
        int res=1;
        while(b)
        {
            if(b&1)
                res=(LL)res*a%MOD;
            a=(LL)a*a%MOD;
            b>>=1;
        }
        return res;
    }
    int qa[N],qb[N];
    void build(int l,int r,int i)
    {
        cnt[i]=sum[i]=0;
        mul[i]=1;
        if(l==r)
        {
            val[i]=mypow(3,qb[l]);
            return ;
        }
        int mid=(l+r)>>1;
        build(l,mid,lson);
        build(mid+1,r,rson);
    }
    void pushdown(int i)
    {
        if(mul[i]!=1)
        {
            mul[lson]=(LL)mul[lson]*mul[i]%MOD;
            mul[rson]=(LL)mul[rson]*mul[i]%MOD;
            sum[lson]=(LL)sum[lson]*mul[i]%MOD;
            sum[rson]=(LL)sum[rson]*mul[i]%MOD;
            mul[i]=1;
        }
    }
    void pushup(int i)
    {
        cnt[i]=cnt[lson]+cnt[rson];
        sum[i]=(sum[lson]+sum[rson])%MOD;
    }
    void update(int l,int r,int pl,int pr,int type,int va,int i)
    {
        if(l>=pl&&r<=pr)
        {
            if(type==1)
            {
                mul[i]=(LL)mul[i]*va%MOD;
                sum[i]=(LL)sum[i]*va%MOD;
            }else
            {
                cnt[i]++;
                sum[i]+=(LL)val[i]*va%MOD;
                if(sum[i]>=MOD)sum[i]-=MOD;
            }
            return ;
        }
        pushdown(i);
        int mid=(l+r)>>1;
        if(mid>=pl)update(l,mid,pl,pr,type,va,lson);
        if(pr>mid)update(mid+1,r,pl,pr,type,va,rson);
        pushup(i);
    }
    int query(int l,int r,int pl,int pr,int type,int i)
    {
        if(l>=pl&&r<=pr)
        {
            if(type==1)return sum[i];
            else return cnt[i];
        }
        pushdown(i);
        int mid=(l+r)>>1;
        int tmp=0;
        if(pl<=mid)tmp+=query(l,mid,pl,pr,type,lson);
        if(pr>mid)tmp+=query(mid+1,r,pl,pr,type,rson);
        if(tmp>=MOD)tmp-=MOD;
        return tmp;
    }
    struct node
    {
        int a,b;
    }s[N];
    bool cmp(node a,node b)
    {
        return a.a<b.a;
    }
    int main() {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            int taila,tailb;
            taila=tailb=0;
            for(int i=0;i<n;++i)
            {
                scanf("%d%d",&s[i].a,&s[i].b);
                qa[taila++]=s[i].a;
                qb[tailb++]=s[i].b;
            }
            sort(s,s+n,cmp);
            sort(qa,qa+taila);
            sort(qb,qb+tailb);
            taila=unique(qa,qa+taila)-qa;
            tailb=unique(qb,qb+tailb)-qb;
            int maxn=tailb-1;
            build(0,maxn,1);
            int ans=0;
            for(int i=0;i<n;++i)
            {
                int x=lower_bound(qb,qb+tailb,s[i].b)-qb;
                int tmp=(LL)mypow(2,s[i].a)*mypow(3,s[i].b)%MOD;
                int cc=0;
                if(x>0)
                {
                    cc=query(0,maxn,0,x-1,2,1);
                    tmp=(LL)tmp*mypow(2,cc)%MOD;
                }
                int tmp2=(LL)mypow(2,s[i].a)*query(0,maxn,x,maxn,1,1)%MOD;
                tmp+=tmp2;
                if(tmp>=MOD)tmp-=MOD;
                ans+=tmp;
                if(ans>=MOD)ans-=MOD;
            //    printf("::%d %d
    ",x,maxn);
                update(0,maxn,x,maxn,1,2,1);
                update(0,maxn,x,x,2,mypow(2,cc),1);
            }
            printf("%d
    ",(ans%MOD+MOD)%MOD);
        }
    
        return 0;
    }
  • 相关阅读:
    addslashes与mysql_real_escape_string的区别
    gcc
    php函数
    JAVA基本类库介绍
    Linux系统精华教程
    CJIAN
    我的未来不是梦! 全新时代
    html标签属性disabled用法 全新时代
    javamail收取邮件demo code 全新时代
    TortoiseSVN安装注意事项及中文语言包安装 全新时代
  • 原文地址:https://www.cnblogs.com/L-Ecry/p/3895562.html
Copyright © 2011-2022 走看看