cdcq

梦幻小鱼干

导航

【HAOI2012】容易题

原题:

 

 

 

 

 

常见思路:不妨先考虑简化的问题

如果没有禁选限制怎么来做?

可以发现a1*a1+a1*a2+...+a1*ak+a2*a1+...+ak*ak=a1*(a1+a2+...+ak)+a2*(a1+...+ak)+...+ak*(a1+...+ak)=(a1+a2+...+ak)*(a1+...+ak)

接着可以想到如果前i个数的答案是f[i],那么f[i+1]=f[i]*1+f[i]*2+...+f[i]*n=f[i]*(1+2+...+n)=f[i]*(1+n)*n/2

即如果没有禁选限制,那么最终答案就是((1+n)*n/2)^m

如果加入禁选呢,可以发现f[i+1]=f[i]*(1+n)*n/2-f[i]*b1-f[i]*b2-...f[i]*bk,其中b是不能选的数

接着就是一个既类似于离散化,又类似于DP的东西

给禁选排个序,每枚举到一个禁选,如果它和上一个禁选不位于同一个位置,那先把中间隔着的没有禁选的位置填满,即ans*=N^(ai-a_{i-1}),其中N=(1+n)*n/2,a表示禁选的位置

然后再把被禁选的位置减去,这时需要引入一个last(即DP中的f[i-1])方便计算,当ans*=N^(ai-a_{i-1})时记录last=N^(ai-a_{i-1}-1)

然后让ans-=last*bi即可

如果当前禁选和上一禁选位于同一个位置,那么无需更新last,直接让ans-=last*bi

注意判断两个一模一样的禁止条件的情况,不要重复减了(样例很良心,包含了这种情况)

最后记得要把最后一个禁选到最后一个位置的空间补齐

确实是个容易题盒盒

 

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #define LL long long
 5 using namespace std;
 6 const int mo=1000000007;
 7 struct nds{LL x,y;}a[110000];
 8 LL n,m,o;
 9 LL qcp(LL x,LL y){
10     LL bwl=1,z=x;
11     for(;y;y>>=1){
12         if(y&1){
13             bwl=bwl*z%mo;
14         }
15         z=z*z%mo;
16     }
17     return bwl;
18 }
19 bool cmp(nds x,nds y){
20     return x.x==y.x ? x.y<y.y : x.x<y.x;
21 }
22 int main(){
23     scanf("%lld%lld%lld",&n,&m,&o);
24     for(int i=1;i<=o;++i){
25         scanf("%lld%lld",&a[i].x,&a[i].y);
26     }
27     sort(a+1,a+o+1,cmp);
28     LL N=(1+n)*n/2%mo;
29     if(o==0){
30         printf("%lld\n",qcp(N,m));
31     }
32     else{
33         LL bwl=1;
34         LL lst=1;
35         for(int i=1;i<=o;++i){
36             if(a[i].x!=a[i-1].x){
37                 lst=bwl*qcp(N,a[i].x-a[i-1].x-1)%mo;
38                 bwl=bwl*qcp(N,a[i].x-a[i-1].x)%mo;
39                 //cout<<bwl<<" "<<lst<<endl;
40                 bwl=(bwl-lst*a[i].y)%mo;
41             }
42             else if(a[i].y!=a[i-1].y){
43                 bwl=(bwl-lst*a[i].y)%mo;
44             }
45             //cout<<bwl<<' '<<lst<<' '<<a[i].x<<' '<<a[i].y<<endl;
46         }
47         bwl=bwl*qcp(N,m-a[o].x)%mo;
48         printf("%lld\n",(bwl+mo)%mo);
49     }
50     return 0;
51 }
View Code

 

posted on 2020-10-17 17:39  cdcq  阅读(111)  评论(0编辑  收藏  举报