2019-12-5 魔数

https://www.cnblogs.com/1625--H/p/12745977.html#_label0
讲得好

前几天有同学准备复试上机刷csp,然后我就想起来有这么个东西还没补来着

xm能进复试的。我只能爪巴。

得两年没写过线段树了。头疼。
一开始写的是 SegTree{val[N<<2];}[32]
发现写不下去了。。。。

#include <bits/stdc++.h>
#define yxn inline
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const ull mod = 2009731336725594113;
const int N = 1e6+2;
ull u[5] = {
314882150829468584,
427197303358170108,
1022292690726729920,
1698479428772363217,
2006101093849356424
};
ull mul(ull a, ull b){
    ull res = 0;
    for(;b;b>>=1){
        if(b & 1) res = (res + a) % mod;
        a = (a + a) % mod;
    }
    return res%mod;
}
int f[33][33];//
ull b[33];//b[28]=1;
void init(){
    map<ull,int>mp;
    queue<ull> q;
    int id=1;
    for(int i=0;i<5;i++){
        q.push(u[i]);
        mp[u[i]]=id++;
    }
    while (!q.empty()){
        ull x=q.front();
        q.pop();
        int p=mp[x];
        for(int i=0;i<5;i++){
            ull s = mul(x,u[i]);
            if(!mp.count(s)){
                f[p][i] = id;//p*i转移到id
                mp[s] = id++;
                q.push(s);
            }
        }
    }
    for(map<ull,int>::iterator it = mp.begin();it!=mp.end();it++)b[it->second]=it->first;
//    for(int i=0;i<32;i++)cout<<(ull)b[i]%mod%2019<<' '<<i<<endl;
    for(int i=1;i<=32;i++){
        for(int j=i;j<=32;j++){
            f[j][i]=f[i][j]=mp[mul(b[i],b[j])%mod];
        }
    }
}
ull tmp[33];
struct SegTree{
    int l,r;
    ull val[33];
    int lazy;
    int res;
    void convert(int target){
        for(int i=1;i<=32;i++)tmp[i] = val[f[i][target]];
        for(int i=1;i<=32;i++)val[i] = tmp[i];
        res = val[28];
        lazy = f[lazy][target];
    }
}c[N<<2];
ull g[1000005][33];
yxn void build(int k,int l,int r){
    c[k].l=l,c[k].r=r;
    if(l==r) {
        for(int i=1;i<=32;i++)c[k].val[i] = g[l][i]%2019;
    }
    else{
        int mid = l+r>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        for(int i=1;i<=32;i++)c[k].val[i]=c[k<<1].val[i]+c[k<<1|1].val[i];
    }
    c[k].lazy=28;
    c[k].res=c[k].val[28];
}
yxn void pushdown(int k){
    if(c[k].lazy==28)return;
    c[k<<1].convert(c[k].lazy);
    c[k<<1|1].convert(c[k].lazy);
    c[k].lazy = 28;
}
yxn ull query(int k,int l,int r){
    if(r<c[k].l||l>c[k].r)return 0;
    if(l<=c[k].l&&r>=c[k].r)return c[k].res;
    pushdown(k);
    int mid = c[k].l+c[k].r>>1;
    int res = 0;
    if(mid >= l) res = query(k<<1,l,r);
    if(mid < r) res = res + query(k<<1|1,l,r);
    return res;
}
yxn void update(int k,int l,int r,ull tmp){
    if(r<c[k].l||l>c[k].r)return;
    if(l<=c[k].l&&r>=c[k].r){
        c[k].convert(tmp);
        return;
    }
    pushdown(k);
    int mid = c[k].l + c[k].r >> 1;
    if(mid >= l) update(k<<1, l, r, tmp);
    if(mid < r) update(k<<1|1, l, r, tmp);
    for(int i=1;i<=32;i++)c[k].val[i] = c[k<<1].val[i] + c[k<<1|1].val[i];
    c[k].res = c[k].val[28];
}
int n,q,l,r;
int main(){
    init();
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=32;j++){
            g[i][j]=(g[i-1][j]+b[j])%mod;
        }
    }
    build(1,1,n);
    while (q--){
        scanf("%d%d",&l,&r);
        int s = query(1,l,r);
        printf("%d
",s);
        s=s%5;
        update(1,l,r,s+1);
    }
}

原文地址:https://www.cnblogs.com/MXang/p/14254639.html