HDU6333 Problem B. Harvest of Apples

考场上看到这个题的时候,我记得这个式子好像是不能化简的= =,所以我就开始想能不能从c(m,0)+c(m,1)+...+c(m,m)轻松推出c(n,0)+c(n,1)+c(n,2)....+c(n,m),因为前者就是2^m,如果能O(1)从m扩大到n就行了,结果发现从

c(m,0)+c(m,1)=sum1          (1)式

推到

c(m+1,0)+c(m+1,1)+..c(m+1,m)=sum2     (2)式

的规律

c(m+1,1)-c(m,1)=c(m,0),c(m+1,2)-c(m,2)=c(m,1),

所以从(1)式推到(2)就是 sum2=sum1+sum1-c(m,n)

然后看到T=1e5,n,m=1e5,突然就想到莫队,因为n加减1就用上面的公式O(1)转移,m加减1就用+c(n,m+1)或者-c(n,m),用lucas+预处理也可以O(1)转移。

打了6场多校,我队第一次做出了非签到题,感觉我很多次发挥都是想到莫队= =,上次湘潭也是莫队+二分树状数组A了一道主席树的题。。。

#include
#define X first
#define Y second
#define pb push_back
#define mk make_pair
#define rep(i,l,r) for(int i=l;i<=r;++i)
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
const int MAXN = 100010;  
const int mod = 1e9 + 7;  

int T,sz;
struct node
{
	int m,n,ind;
}a[maxn];
LL sum;
LL ans[maxn];
LL inv[MAXN + 10], fac[MAXN + 10];

void init()    
{    
    inv[0] = fac[0] = inv[1] = fac[1] = 1;    
    for(int i = 1; i < MAXN; i++)    
    fac[i] = fac[i - 1] * i % mod;    
    for(int i = 2; i < MAXN; i++)    
    inv[i] = (mod - (mod / i)) * inv[mod % i] % mod;//lucas?????    
    for(int i = 1; i < MAXN; i++)    
    inv[i] = inv[i - 1] * inv[i] % mod;     
}  
inline LL C(int n, int m)//???? C n,m     
{    
    if(na[i].n)
		{
			sum=(1ll*((sum+C(r-1,l))%mod)*inv[2])%mod;
			r--;
		}
		while(la[i].m)
		{
			l--;
			sum=(sum-C(r,l+1)+mod)%mod;
		}
		ans[a[i].ind]=sum;
	}
}

inline void print()
{
	for(int i=1;i<=T;i++)
		printf("%lld\n",ans[i]);
}

int main()
{
    init();
    prework();
    mainwork();
    print();
    return 0;
}

 

你可能感兴趣的:(莫队)