今天依旧是链表
emmm昨天以为是周日
没发
网课还是很烦
明天决定不上了
今天不多说
看题就ok
题目背景
作为唯一一道有背景的题,此题由出题人基于 @Ecrade_ 的原创题“子集”拓展而来。
“子集”便是本题中 k=n-1k=n−1 的情况。
题目描述
给定一个有 nn 个元素的序列 aa。
定义一个有 xx 个元素的序列 ss 的值为:
\sum \limits _{i=1} ^ x s_i \times \prod \limits _{i=1} ^ x s_i
i=1
∑
x
s
i
×
i=1
∏
x
s
i
将序列 aa 的一个有 xx 个元素的子序列表示为 s = {a_{p_1},a_{p_2},…,a_{p_x}}s={a
p
1
,a
p
2
,…,a
p
x
},其中 pp 为严格单调递增的序列,1 \le p_1 \le p_x \le n1≤p
1
≤p
x
≤n 。
给定整数 kk,定义序列 aa 的一个有 xx 个元素的合法的子序列 ss 需满足 p_x - p_1 \le kp
x
−p
1
≤k。
求序列 aa 的所有合法子序列的值之和对 modmod 取模的值。
输入格式
第一行三个整数,n,k,modn,k,mod 。
第二行 nn 个整数,a_ia
i
。
输出格式
一行一个整数表示答案对 modmod 取模的值。
原题链接:https://www.luogu.com.cn/problem/P6856
我的答案:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
#define G() Cr = getchar()
#define LL long long
LL Xr, Fr; char Cr;
inline LL rd() {
Xr = 0, Fr = 1, G();
while(Cr < '0' || Cr > '9') {if(Cr == '-') Fr = -1; G();}
while(Cr >= '0' && Cr <= '9') Xr = (Xr<<1) + (Xr<<3) + (Cr&15), G();
return Xr * Fr;
}
#define MAX_N 1000005
LL n, k, mod;
LL va[MAX_N], f[MAX_N][3], b[MAX_N][3], l[MAX_N], r[MAX_N], ans, s; // 0 -> from left ; 1 -> from right
LL work( LL L, LL R ) {
if( L == R ) return va[L] * va[L] % mod;
if( l[L] == l[R] ) return f[R][0];
LL x, y, A, B;
x = f[L][1], y = f[R][0];
A = b[L][1], B = b[R][0];
return ( x + y + A * y % mod + B * x % mod ) % mod;
}
int main() {
n = rd(), k = rd(), mod = rd();
for( int i = 1; i <= n; i++ ) va[i] = rd();
if(!k) {
for( int i = 1; i <= n; i++ ) ans = ( ans + va[i] * va[i] ) % mod;
cout << ans;
return 0;
}
for( int i = 1; i <= n; i++ ) l[i] = ( i - 1 ) / k * k + 1, r[i] = ( ( i - 1 ) / k + 1 ) * k;
for( int i = 1; i <= n; i++ ) {
if( i == l[i] ) b[i][0] = va[i], f[i][0] = va[i] * va[i] % mod;
else {
f[i][0] = (va[i] * va[i] % mod * ( 1 + b[i-1][0] ) % mod + f[i-1][0] * ( 1 + va[i] ) % mod ) % mod;
b[i][0] = ( b[i-1][0] * ( 1 + va[i] ) + va[i] ) % mod;
}
}
for( int i = n; i >= 1; i-- ) {
if( i == r[i] ) b[i][1] = va[i], f[i][1] = va[i] * va[i] % mod;
else {
f[i][1] = (va[i] * va[i] % mod * ( 1 + b[i+1][1] ) % mod + f[i+1][1] * ( 1 + va[i] ) % mod ) % mod;
b[i][1] = ( b[i+1][1] * ( 1 + va[i] ) + va[i] ) % mod;
}
}
for( int i = k + 1; i < n; i++ )
ans = ( ans + work(i-k,i) - work(i-k+1,i) + mod ) % mod;
ans = ( ans + work(n-k,n) ) % mod;
cout << ans;
}