线段树与树状数组
树状数组
#include <bits/stdc++.h>
using namespace std;
int n,m;
typedef long long ll;
ll tre[500001],k,a;
int opt;
ll lowbit(ll x)
{
return (x & (-x));
}
void add(ll x,ll k)
{
for ( ; x <= n; x += lowbit(x))
{
tre[x] += k;
}
}
ll query(ll x)
{
ll ans = 0;
for ( ; x; x -= lowbit(x))
{
ans += tre[x];
}
return ans;
}
int main()
{
cin >> n >> m;
for (ll i = 1; i <= n; i++)
{
cin >> a;
add(i,a);
}
while(m--)
{
cin >> opt >> a >> k;
if(opt == 1)
{
add(a,k);
}
else
{
cout << query(k) - query(a - 1) << endl;
}
}
return 0;
}
线段树
#include <bits/stdc++.h>
using namespace std;
#define ull long long
int n,m;
ull va[400001],tag[400001],tag2[400001],sum[400001],x[400001],mo;
ull ls(int p)
{
return (p << 1);
}
ull rs(int p)
{
return (p << 1 | 1);
}
void pushup(int p)
{
sum[p] = ( sum[ls(p)] + sum[rs(p)] ) % mo;
}
void f(int p,int l,int r,ull k,ull k2)
{
sum[p] = (sum[p] * k2 ) % mo;
sum[p] = (sum[p] + k * (r - l + 1) ) % mo;
tag2[p] = (tag2[p] * k2) % mo;
tag[p] = (tag[p] * k2 ) % mo;
tag[p] = (tag[p] + k ) % mo;
}
void pushdown(int p,int l,int r)
{
int mid = ((l + r) >> 1);
f(ls(p),l,mid,tag[p],tag2[p]);
f(rs(p),mid + 1,r,tag[p],tag2[p]);
tag[p] = 0;
tag2[p] = 1;
}
ull query(int gl,int gr,int nl,int nr,int p)
{
ull res = 0;
if(gl <= nl && gr >= nr)return sum[p] % mo;
int mid = ((nr + nl) >> 1);
pushdown(p,nl,nr);
if(gl <= mid)res += query(gl,gr,nl,mid,ls(p));
if(gr > mid)res += query(gl,gr,mid + 1,nr,rs(p));
return (res % mo);
}
void add(int gl,int gr,int nl,int nr,int p,ull k,int way)
{
if(nl >= gl && nr <= gr)
{
if(way)
{
sum[p] = (sum[p] * k) % mo;
tag[p] = (tag[p] * k) % mo;
tag2[p] = (tag2[p] * k) % mo;
return ;
}
sum[p] = (sum[p] + k * (nr - nl + 1) ) % mo;
tag[p] = ( tag[p] + k ) % mo;
return ;
}
pushdown(p,nl,nr);
int mid = ((nr + nl) >> 1);
if(gl <= mid)add(gl,gr,nl,mid,ls(p),k,way);
if(gr > mid)add(gl,gr,mid + 1,nr,rs(p),k,way);
pushup(p);
}
void build(int p,int l,int r)
{
tag[p] = 0;
tag2[p] = 1;
if(l == r)
{
sum[p] = x[l];
return ;
}
int mid = ( (l + r) >> 1 );
build(ls(p),l,mid);
build(rs(p),mid+ 1,r);
pushup(p);
}
int main()
{
scanf(" %d %d %lld",&n,&m,&mo);
for (int i = 1; i <= n; i++)
{
scanf(" %lld",&x[i]);
x[i] %= mo;
}
build(1,1,n);
int opt;
ull a,b,c;
while(m--)
{
scanf(" %d",&opt);
if(opt == 1)
{
scanf(" %lld %lld %lld",&a,&b,&c);
add(a,b,1,n,1,(c % mo),1);
}
else if(opt == 2)
{
scanf(" %lld %lld %lld",&a,&b,&c);
add(a,b,1,n,1,(c % mo),0);
}
else
{
scanf(" %lld %lld",&a,&b);
//cout << "pp" << opt << "pp";
printf("%lld\n",query(a,b,1,n,1));
}
}
return 0;
}
运算优先级问题
先乘后加
lazy tag是一体的
浙公网安备 33010602011771号