CF-1151

E. Number of Components

题意

一条链, 每个点的权值为 $a_i(1\le a_i\le n)$ , $f(l,r)$ 表示仅保留权值在 $[l,r]$ 之间的点的联通分量

题解

统计每个点的贡献, 只有当取 $a_i$ 不取 $a_{i+1}$ 时, $a_i$ 才有贡献

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <bits/stdc++.h>
using namespace std;
#define forl(i, l, r) for (int i = l; i <= r; i++)
#define forr(i, r, l) for (int i = r; i >= l; i--)
#define for1(i, n) for (int i = 1; i <= n; i++)
#define fro1(i, n) for (int i = 1; i <= n; i++)
#define for0(i, n) for (int i = 0; i < n; i++)
#define fro0(i, n) for (int i = 0; i < n; i++)
#define meminf(a) memset(a, inf, sizeof(a))
#define mem_1(a) memset(a, -1, sizeof(a))
#define mem0(a) memset(a, 0, sizeof(a))
#define oper(type) bool operator <(const type y)const
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef pair<long long, long long> pll;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef unsigned long long ull;
typedef vector<int> vii;
typedef long double db;
typedef long long ll;
typedef int itn;
int in(int &a,int &b,int &c,int &d){return scanf("%d%d%d%d",&a,&b,&c,&d);}
int in(int &a,int &b,int &c){return scanf("%d%d%d",&a,&b,&c);}
int in(int &a,int &b){return scanf("%d%d",&a,&b);}
int in(ll &a){return scanf("%lld",&a);}
int in(int &a){return scanf("%d",&a);}
int in(char *s){return scanf("%s",s);}
int in(char &s){return scanf("%c",&s);}
int in(db &a){return scanf("%Lf",&a);}
void out(int a){printf("%d",a);}
void outln(int a){printf("%d\n",a);}
void out(ll a){printf("%lld",a);}
void outln(ll a){printf("%lld\n",a);}
const db pi = acos((db)-1);
const ll inf =0x3f3f3f3f;
const db eps = 1e-8;
const int N = 1.1e5;
const ll mod = 1e9+7;
int sign(db a) { return a < -eps ? -1 : a > eps;}
int db_cmp(db a, db b){ return sign(a-b); }

int main() {
#ifdef PerpEternal
// freopen("/Users/perpeternal/Documents/Sketch/data/in.dat", "r", stdin);
// freopen("/Users/perpeternal/Documents/Sketch/data/out.dat", "w", stdout);
#endif
//ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n,x;
ll pre;
in(n);
ll ans=0;
in(pre);
ans+=pre*(n+1-pre);
for0(i,n-1){
in(x);
if(x>pre){
ans+=(x-pre)*(n+1-x);
pre=x;
}else if(x<pre){
ans+=(pre-x)*x;
pre=x;
}
}
outln(ans);
return 0;
}

F. Sonya and Informatics

题意

数组 $a$ 有 $n$ 个数, 这些数由 $0,1$ 构成, 等概率交换任意两个数的位置, 问最后得到一个不下降的数列的概率, 答案对 $1e9+7$ 取模

题解

设 $x$ 表示 $0$ 的个数, $dp[i][j]$ 表示操作 $i$ 次后前 $x$ 个数中 $0$ 的个数为 $j$ 的概率, 答案为 $dp[k][x]$

可以发现状态转移方程与 $i$ 无关, 可以用矩阵快速幂做

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <bits/stdc++.h>
using namespace std;
#define forl(i, l, r) for (int i = l; i <= r; i++)
#define forr(i, r, l) for (int i = r; i >= l; i--)
#define for1(i, n) for (int i = 1; i <= n; i++)
#define fro1(i, n) for (int i = 1; i <= n; i++)
#define for0(i, n) for (int i = 0; i < n; i++)
#define fro0(i, n) for (int i = 0; i < n; i++)
#define meminf(a) memset(a, inf, sizeof(a))
#define mem_1(a) memset(a, -1, sizeof(a))
#define mem0(a) memset(a, 0, sizeof(a))
#define memcp(a,b) memcpy(a,b,sizeof(b))
#define oper(type) bool operator <(const type y)const
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef pair<long long, long long> pll;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef unsigned long long ull;
typedef vector<int> vii;
typedef long double db;
typedef long long ll;
typedef int itn;
int in(int &a,int &b,int &c,int &d){return scanf("%d%d%d%d",&a,&b,&c,&d);}
int in(int &a,int &b,int &c){return scanf("%d%d%d",&a,&b,&c);}
int in(int &a,int &b){return scanf("%d%d",&a,&b);}
int in(ll &a){return scanf("%lld",&a);}
int in(int &a){return scanf("%d",&a);}
int in(char *s){return scanf("%s",s);}
int in(char &s){return scanf("%c",&s);}
int in(db &a){return scanf("%Lf",&a);}
void out(int a){printf("%d",a);}
void outln(int a){printf("%d\n",a);}
void out(ll a){printf("%lld",a);}
void outln(ll a){printf("%lld\n",a);}
const db pi = acos((db)-1);
const ll inf =0x3f3f3f3f;
const db eps = 1e-8;
const int N = 2.1e5;
const ll mod = 1e9+7;
int sign(db a) { return a < -eps ? -1 : a > eps;}
int db_cmp(db a, db b){ return sign(a-b); }

int a[110];
ll matrix[110][110];
ll qPow(ll a, ll b, ll c) { //求(a^b) % c
ll ret = 1;
while (b) {
if (b & 0x1) ret = ret * a % c;
a = a * a % c;
b >>= 1;
}
return ret;
}
int n,k,x=0,xx=0;
void fun(ll c[110][110],ll b[110][110]){
ll tmp[110][110];
mem0(tmp);
for0(i,x+1)
for0(j,x+1)
for0(k,x+1)tmp[i][j]=(tmp[i][j]+c[i][k]*b[k][j])%mod;
memcp(c,tmp);
}
ll Com(ll a){
if(a<2)return 0;
return a*(a-1)/2;
}
int main() {
#ifdef PerpEternal
// freopen("/Users/perpeternal/Documents/Sketch/data/in.dat", "r", stdin);
// freopen("/Users/perpeternal/Documents/Sketch/data/out.dat", "w", stdout);
#endif
//ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
// cout<<qPow(3,mod-2,mod)<<endl;
in(n,k);
ll C=n*(n-1)/2,inv_C=qPow(C,mod-2,mod);
inv_C=qPow(inv_C,k,mod);
for1(i,n){
in(a[i]);
if(!a[i])x++;
}
ll A=Com(x),B=Com(n-x);
for1(i,x)if(!a[i])xx++;
int minn=max(0,2*x-n);
// cout<<x<<' '<<xx<<' '<<minn<<endl;
forl(i,minn,x){
int p1=0,p2=0;
if(i-1>=minn){
matrix[i-1][i]=p1=(x-i+1)*(x-i+1);
}
if(i+1<=x){
matrix[i+1][i]=p2=(i+1)*(n-2*x+i+1);
}
matrix[i][i]=A+B+i*(x-i)+(n-2*x+i)*(x-i);
}
ll an[110][110];
for0(i,x+1)an[i][i]=1;
while(k){
if(k&1)fun(an,matrix);
fun(matrix,matrix);
k>>=1;
}
outln(an[xx][x]*inv_C%mod);
return 0;
}