首页 > 其他 > 详细

【BZOJ2751】【HAOI2012】容易题(easy) 快速幂快速乘

时间:2015-03-28 08:52:27      阅读:534      评论:0      收藏:0      [点我收藏+]

链接:

#include <stdio.h>
int main()
{
    puts("转载请注明出处[vmurder]谢谢");
    puts("网址:blog.csdn.net/vmurder/article/details/44684583");
}

题解:

询问只有10万个,所以有相同性质的连一块的点很多。
所以我们把109点分成最多2?105块。然后就随便乱搞了。

分成2?105块的过程是先把点排个序,然后就对每个点暴力往下删了。
然后分完了以后就是把所有的点的选择个数x乘起来就行了。长度为y那就乘xy

然后可能会爆,所以需要快速乘,请见mul部分。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 201000
#define mod 1000000007
using namespace std;
struct Eli
{
    long long x,y,z;
    void read(){cin>>x>>y;}
    Eli(long long _x=0,long long _y=0,long long _z=0):x(_x),y(_y),z(_z){}
    bool operator <(const Eli &A)const
    {return x==A.x?y<A.y:x<A.x;}
}eli[N],src[N];
long long n,m,p,cnt;
long long mul(long long a,long long b)
{
    long long ret=0;
    while(b)
    {
        if(b&1)ret=(ret+a)%mod;
        a<<=1,a%=mod,b>>=1;
    }
    return ret;
}
long long power(long long a,long long b)
{
    long long ret=1;
    while(b)
    {
        if(b&1)ret=mul(ret,a);
        a=mul(a,a),b>>=1;
    }
    return ret;
}
long long ans=0;
long long lsum[N],rsum[N];
int main()
{
    int i,j,k;

    cin>>n>>m>>p;
    for(i=1;i<=p;i++)eli[i].read();
    sort(eli+1,eli+p+1);

    long long sum=n*(n+1)/2;
    long long t=sum,last=1ll,r=n;
    for(i=1;i<=p;i++)
    {
        if(eli[i].x!=last)
        {
            src[++cnt]=Eli(1,r%mod,t%mod);
            k=eli[i].x-last;
            if(k>1)src[++cnt]=Eli(k-1,n%mod,sum%mod);
            last=eli[i].x,r=n-1,t=sum-eli[i].y;
        }
        else {
            if(eli[i].y==eli[i-1].y)continue;
            r--,t-=eli[i].y;
        }
    }
    src[++cnt]=Eli(1,r%mod,t%mod);
    k=m-last;
    if(k)src[++cnt]=Eli(k,n%mod,sum%mod);

/*  lsum[0]=rsum[cnt+1]=1ll;
    for(i=1;i<=cnt;i++)
    {
        lsum[i]=lsum[i-1]*power(src[i].y,src[i].x)%mod;
    }
    for(i=cnt;i;i--)
    {
        rsum[i]=rsum[i+1]*power(src[i].y,src[i].x)%mod;
    }
    for(i=1;i<=cnt;i++)
    {
        ans=(ans+src[i].x*src[i].z%mod*lsum[i-1]%mod*rsum[i+1]%mod)%mod;
    }*/
        ans=1;
    for(i=1;i<=cnt;i++)
    {
        ans=ans*power(src[i].z,src[i].x)%mod;
    }

    cout<<ans<<endl;
    return 0;
}

【BZOJ2751】【HAOI2012】容易题(easy) 快速幂快速乘

原文:http://blog.csdn.net/vmurder/article/details/44684583

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!