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);
}
}