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 }