线段树维护F[ai-1], F[ai-1 + 1], F[ai-1 - 1], F[ai+1], F[ai+1 + 1], F[ai+1 - 1]
以及两两乘积和
加一的时候可以直接用递推式用保存的F值求出新的值
减一的时候也可以解方程求值
然后 写码农题
然而此题常数太卡 在jzoj上都600ms了 BZ上还是过不去 弃疗了
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>
#define SF scanf
#define PF printf
using namespace std;
typedef int LL;
inline int read() {
int x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar(); }
return x*f;
}
const int MOD = 1000000007;
const int MAXN = 300000;
int a, b, n, m, inv, L, R, Y, Z;
int p[MAXN+10][4];
int pow_mod(int x, int k) {
int ret = 1;
while(k) {
if(k & 1) ret = 1LL * ret * x % MOD;
x = 1LL * x * x % MOD;
k >>= 1;
}
return ret;
}
struct Matrix {
int a[3][3], r, c;
void set(int n) {
memset(a, 0, sizeof(a));
r = c = n;
for(int i = 0; i < n; i++) a[i][i] = 1;
}
Matrix operator * (const Matrix &t) const {
Matrix ret; memset(ret.a, 0, sizeof(ret.a));
ret.r = r; ret.c = t.c;
for(int i = 0; i < r; i++)
for(int k = 0; k < c; k++)
for(int j