P1001的线段树解法
zhangchengyan · · 个人记录
那么难的题目怎么可以少得了线段树呢(我的挚爱
Code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mul[400005],ans[400005],add[400005],a[100005],mod,n,m,opt,l,r,x;
void build(ll p,ll l,ll r)
{
mul[p]=1;
if(l==r)
{
ans[p]=a[l]%mod;
return;
}
ll mid=(l+r)/2;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
ans[p]=ans[p<<1]+ans[p<<1|1];
}
void push_down(ll p,ll l,ll r)
{
ll mid=(l+r)/2;
ans[p<<1]=(ans[p<<1]*mul[p]+add[p]*(mid-l+1))%mod;
ans[p<<1|1]=(ans[p<<1|1]*mul[p]+add[p]*(r-mid))%mod;
mul[p<<1]=(mul[p<<1]*mul[p])%mod;
mul[p<<1|1]=(mul[p<<1|1]*mul[p])%mod;
add[p<<1]=(add[p<<1]*mul[p]+add[p])%mod;
add[p<<1|1]=(add[p<<1|1]*mul[p]+add[p])%mod;
add[p]=0,mul[p]=1;
}
void update1(ll p,ll l,ll r,ll ql,ll qr,ll k)
{
if(ql<=l&&r<=qr)
{
ans[p]=(ans[p]*k)%mod;
mul[p]=(mul[p]*k)%mod;
add[p]=(add[p]*k)%mod;
return;
}
push_down(p,l,r);
ll mid=(l+r)/2;
if(ql<=mid)
update1(p<<1,l,mid,ql,qr,k);
if(qr>mid)
update1(p<<1|1,mid+1,r,ql,qr,k);
ans[p]=ans[p<<1]+ans[p<<1|1];
}
void update2(ll p,ll l,ll r,ll ql,ll qr,ll k)
{
if(ql<=l&&r<=qr)
{
ans[p]=(ans[p]+k*(r-l+1))%mod;
add[p]=(add[p]+k)%mod;
return;
}
push_down(p,l,r);
ll mid=(l+r)/2;
if(ql<=mid)
update2(p<<1,l,mid,ql,qr,k);
if(qr>mid)
update2(p<<1|1,mid+1,r,ql,qr,k);
ans[p]=ans[p<<1]+ans[p<<1|1];
}
ll query(ll p,ll l,ll r,ll ql,ll qr)
{
if(ql<=l&&r<=qr)
return ans[p];
push_down(p,l,r);
ll mid=(l+r)/2;
ll ans=0;
if(ql<=mid)
ans+=query(p<<1,l,mid,ql,qr);
if(qr>mid)
ans+=query(p<<1|1,mid+1,r,ql,qr);
return ans%mod;
}
int main()
{
ios::sync_with_stdio(0);
mod=1e18;
n=2;
for(int i=1;i<n;++i)
cin>>a[i];
build(1,1,n);
int x;
cin>>x;
update2(1,1,n,2,2,x);
update1(1,1,n,1,2,1);
cout<<query(1,1,n,1,n);
return 0;
}
提交记录链接