【HAOI2012】容易题

终于自己做出一道题了quq

原题:

为了使得大家高兴,小Q特意出个自认为的简单题(easy)来满足大家,这道简单题是描述如下:
有一个数列A已知对于所有的A[i]都是1~n的自然数,并且知道对于一些A[i]不能取哪些值,我们定义一个数列的积为该数列所有元素的乘积,要求你求出所有可能的数列的积的和 mod 1000000007的值,是不是很简单呢?呵呵!

n<=10^9,m<=10^9,k<=10^5,1<=y<=n,1<=x<=m

这道题挺有意思的,用到了很多基础的知识(其实就是因为简单好写容易AC_(:3 」∠)_

小学级结论:

假设三个位置分别能用三个数a1,a2,a3,b1,b2,b3,c1,c2,c3,手玩一下就可以发现答案是(a1+a2+a3)*(b1+b2+b3)*(c1+c2+c3)

然后每个位置初始的和是(1+n)*n/2,如果有数不能选就直接减掉,数据很良心地提示可能会有重复的(如果不提示我估计想不到

然后搞一搞就行了

注意到m<=1e9,时空爆炸

其实也很好搞,离散化一个,先计算有数被删掉的,剩下的位置的数的和都是(1+n)*n/2,快速幂搞一搞就行了

判重怎么办呐

最开始我想的是set,map,或者搞个平衡树?

然后发现,搞个毛啊,离线即可

这么简单的题WA了两发quq(最开始没考虑到m<=1e9没离散直接从1到m计算了

还要提升思考的精细程度啊……
代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 #define ll long long
 8 const int dalao=1000000007;
 9 int rd(){int z=0,mk=1;  char ch=getchar();
10     while(ch<'0'||ch>'9'){if(ch=='-')mk=-1;  ch=getchar();}
11     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
12     return z*mk;
13 }
14 struct dcd{int x,y;}a[110000];
15 bool cmp(dcd x,dcd y){  return (x.x==y.x)?(x.y<y.y):(x.x<y.x);}
16 int n,m,t;  ll M;
17 ll bwl[110000];
18 int c[110000],b[110000],tt=0;
19 ll qckpw(ll x,int y){
20     ll z=1,bs=x;
21     while(y){
22         if(y&1)  z=(z*bs)%dalao;
23         bs=(bs*bs)%dalao;
24         y>>=1;
25     }
26     return z;
27 }
28 int bnrsch(ll x){
29     int l=1,r=tt,md;
30     while(l+1<r)  md=(l+r)>>1,(b[md]<=x ? l : r)=md;
31     return b[r]==x ? r : l;
32 }
33 int main(){//freopen("ddd.in","r",stdin);
34     cin>>m>>n>>t;  M=((ll)(1+m)*m/2)%dalao;
35     for(int i=1;i<=t;++i)  a[i].x=rd(),a[i].y=rd(),c[i]=a[i].x;
36     sort(a+1,a+t+1,cmp);
37     sort(c+1,c+t+1);
38     for(int i=1;i<=t;++i)if(c[i]!=c[i-1])  b[++tt]=c[i];
39     for(int i=1;i<=tt;++i)  bwl[i]=M;
40     for(int i=1;i<=t;++i)if(!(a[i].x==a[i-1].x && a[i].y==a[i-1].y))
41         bwl[bnrsch(a[i].x)]=(bwl[bnrsch(a[i].x)]-a[i].y+dalao)%dalao;
42     ll ans=1;
43     for(int i=1;i<=tt;++i)  ans=(ans*bwl[i])%dalao;
44     cout<<(ans*qckpw(M,n-tt))%dalao<<endl;
45     return 0;
46 }
View Code