luogu P3773 [CTSC2017]吉夫特

传送门

跟10-17B君的第二题有一点点相似之处。

先用卢卡斯定理把组合数展开,发现a能转移到b的条件是b是a的子集。a[i]互不相同,p[a[i]]=i记录下a[i]的位置,从大到小枚举a[i],枚举a[i]的子集,如果位置在a[i]后面就转移。

 1 //Achen
 2 #include<bits/stdc++.h>
 3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
 4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
 5 #define Formylove return 0
 6 const int N=233337,p=1000000007;
 7 typedef long long LL;
 8 typedef double db;
 9 using namespace std;
10 int n,a[N],pos[N],f[N],up;
11 LL ans;
12 
13 template<typename T> void read(T &x) {
14     char ch=getchar(); x=0; T f=1;
15     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
16     if(ch=='-') f=-1,ch=getchar();
17     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
18 }
19 
20 //#define ANS
21 int main() {
22 #ifdef ANS
23     freopen("1.in","r",stdin);
24     //freopen("1.out","w",stdout);
25 #endif
26     read(n); 
27     For(i,1,n) {
28         read(a[i]);
29         pos[a[i]]=i;
30         up=max(up,a[i]);
31     }
32     Rep(i,up,1) if(pos[i]) {
33         for(int s=((i-1)&i);s;s=((s-1)&i)) {
34             if(pos[s]>pos[i]) 
35                 (f[s]+=f[i]+1)%=p;
36         }
37         ans=(ans+f[i])%p;
38     }
39     printf("%lld\n",ans);
40     Formylove;
41 }
View Code

 

posted @ 2018-10-22 19:18  啊宸  阅读(175)  评论(0编辑  收藏  举报