BFS搜出所有转移状态 然后+线段树+懒标记+__int128乘法运算+ 动态规划优化build函数的节点初始化
少了任何一个优化都过不去
一个优化都不少也有可能过不去,时间卡的太极限了,可能还有极致的优化,暂时还没想到...
#include
#define ull unsigned long long
using namespace std;
const ull mod = 2009731336725594113;
const int N = 1e6+10;
unordered_map mp;
ull f[33],g[33][33],a[N][33];
ull Q[33];
int n, q, id;
ull U[5] = {
314882150829468584,
427197303358170108,
1022292690726729920,
1698479428772363217,
2006101093849356424
};
struct SegTree{
int l,r,tag,res;
int s[33];
}t[N << 2];
void pushup(int u)
{
for(int i = 1; i <= 32; ++i)
t[u].s[i] = t[u<<1].s[i] + t[u<<1|1].s[i];
t[u].res = t[u].s[28];
}
void build(int u,int l,int r)
{
t[u].l = l, t[u].r = r;
if(l == r)
{
for(int i = 1; i <= 32; ++i) t[u].s[i] = a[l][i] % 2019;
t[u].res = t[u].s[28];
t[u].tag = 0;
}
else
{
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
t[u].tag = 0;
}
}
void init()
{
int hh = 0, tt = -1;
for(int i=0;i<5;i++) Q[++ tt] = U[i], mp[U[i]] = ++ id;
while(hh <= tt)
{
ull x = Q[hh ++]; f[mp[x]] = x;
for(int i=0;i<5;i++)
{
ull t = (__int128)x * U[i] % mod;
if(mp[t]) continue;
mp[t] = ++ id;
Q[++ tt] = t;
}
}
for(int i = 1; i <= id; ++i)
for(int j = 1; j <= id; ++j)
g[i][j] = g[j][i] = mp[(__int128)f[i] * f[j] % mod];
}
void eval(int u,int tag)
{
static int tmp[40];
for(int i = 1; i <= id; ++i) tmp[i] = t[u].s[g[i][tag]];
for(int i = 1; i <= id; ++i) t[u].s[i] = tmp[i];
t[u].res = t[u].s[28];
if(t[u].tag == 0) t[u].tag = tag;
else t[u].tag = g[t[u].tag][tag];
}
void pushdown(int u)
{
if(t[u].tag)
{
eval(u << 1, t[u].tag); eval(u << 1 | 1, t[u].tag);
t[u].tag = 0;
}
}
int ask(int u,int l,int r)
{
if(t[u].l >= l && t[u].r <= r) return t[u].res;
pushdown(u);
int mid = t[u].l + t[u].r >> 1, res = 0;
if(mid >= l) res = ask(u << 1, l, r);
if(mid < r) res = res + ask(u << 1 | 1, l, r);
return res;
}
void modify(int u,int l,int r,int k)
{
if(t[u].l >= l && t[u].r <= r){
eval(u, k + 1);
return;
}
pushdown(u);
int mid = t[u].l + t[u].r >> 1;
if(mid >= l) modify(u*2, l, r, k);
if(mid < r) modify(u*2+1, l, r, k);
pushup(u);
}
int main()
{
init();
scanf("%d%d", &n, &q);
// 优化 __int128乘法也超时
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= id; ++j)
if(i == 1) a[i][j] = f[j] % mod;
else a[i][j] = (a[i - 1][j] + f[j]) % mod;
build(1, 1, n);
while(q--){
int l, r;
scanf("%d%d", &l, &r);
int res = ask(1, l, r);
printf("%d\n", res);
modify(1, l, r, res % 5);
}
}
代码参考https://www.cnblogs.com/1625--H/p/12745977.html