CCF CSP 2019-12-05 魔数

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

你可能感兴趣的:(BFS,线段树,线段树,bfs)