https://www.luogu.org/problemnew/show/P3373
区间查询,区间修改(+,*)
贴个模板(上课去了……)╮(╯▽╰)╭
#include <bits/stdc++.h>
#define ll long long
#define Max 100002
using namespace std;
ll a[Max];
ll p;//取摸的
/*放里面编译器提示段错误所以把下面三行从struct拿出来了*/
ll sum[Max << 2];
ll lazy_add[Max << 2];
ll lazy_mulv[Max << 2];
struct sgt
{
#define ls o << 1
#define rs o << 1 | 1
///上
void PushUp(int o)
{
sum[o] = (sum[ls] + sum[rs])%p;
}
//下
void PushDown(int o,int l,int r,int mid,int lson,int rson)
{
//*
lazy_mulv[lson] = (lazy_mulv[lson] * lazy_mulv[o]) % p;
lazy_mulv[rson] = (lazy_mulv[rson] * lazy_mulv[o]) % p;
lazy_add[lson] = (lazy_add[lson] * lazy_mulv[o]) % p;
lazy_add[rson] = (lazy_add[rson] * lazy_mulv[o]) % p;
sum[lson] = (sum[lson] * lazy_mulv[o]) % p;
sum[rson] = (sum[rson] * lazy_mulv[o]) % p;
lazy_mulv[o] = 1;
//+
lazy_add[lson] = (lazy_add[lson] + lazy_add[o]) % p;
lazy_add[rson] = (lazy_add[rson] + lazy_add[o]) % p;
sum[lson] = (sum[lson] + (mid - l + 1) * lazy_add[o]) % p;
sum[rson] = (sum[rson] + (r - mid) * lazy_add[o]) % p;
lazy_add[o] = 0;
}
void build(int o,int l,int r)
{
lazy_add[o] = 0;
lazy_mulv[o] = 1;
if (l == r)
sum[o] = a[l];
else
{
int mid = (l + r) >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
PushUp(o);
}
}
//区间更新 [a,b]+x;
void Update_add(int o, int l, int r, int a, int b, int x)
{
if(l>=a&&r<=b)
{
lazy_add[o] = (lazy_add[o] + x) % p;
sum[o] = (sum[o] + (r - l + 1) * x) % p;
return;
}
else
{
int mid = (l + r) >> 1;
if(lazy_add[o]||lazy_mulv[o]!=1)
PushDown(o, l, r, mid, ls, rs);
if(a<=mid)
Update_add(ls, l, mid, a, b, x);
if(b>mid)
Update_add(rs, mid + 1, r, a, b, x);
PushUp(o);
}
}
void Update_multi(int o,int l,int r,int a,int b,int x)
{
if(l>=a&&r<=b)
{
lazy_mulv[o] = (lazy_mulv[o] * x) % p;
lazy_add[o] = (lazy_add[o] * x) % p;
sum[o] = (sum[o] * x) % p;
}else
{
int mid = (l + r) >> 1;
if(lazy_mulv[o]!=1||lazy_add[o])
PushDown(o, l, r, mid, ls, rs);
if(a<=mid)
Update_multi(ls, l, mid, a, b, x);
if(b>mid)
Update_multi(rs, mid + 1, r, a, b, x);
PushUp(o);
}
}
//区间查询
ll Query(int o,int l,int r,int a,int b)
{
ll ans = 0;
if (l >= a && r <= b)
return sum[o]%p;
else
{
int mid = (l + r) >> 1;
if(lazy_add[o]||lazy_mulv[o]!=1)
PushDown(o, l, r, mid, ls, rs);
if(a<=mid)
ans += Query(ls, l, mid, a, b);
if(b>mid)
ans += Query(rs, mid + 1, r, a, b);
return ans%p;
}
}
};
int n, m, q;
int x, y, k;
int main()
{
sgt tree;
scanf("%d%d%lld", &n, &m, &p);
for (int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
tree.build(1, 1, n);
for (int i = 1; i <= m;i++)
{
scanf("%d", &q);
if(q==1)
{
scanf("%d%d%d", &x, &y, &k);
tree.Update_multi(1, 1, n, x, y, k);
}if(q==2)
{
scanf("%d%d%d", &x, &y, &k);
tree.Update_add(1, 1, n, x, y, k);
}
else if(q==3)
{
scanf("%d%d", &x, &y);
printf("%lld\n", tree.Query(1, 1, n, x, y));
}
}
return 0;
}
一般的线段树操作,单点修改,单点查询,区间修改,区间查询 (加,减)
#include <bits/stdc++.h>
#define ll long long
#define Max 50002
using namespace std;
int n,p,a,b,m,x,y,ans;
struct node
{
int l,r,w,f;
}tree[Max<<2];
//建树
inline void build(int k,int l,int r)
{
tree[k].l=l,tree[k].r=r;
if(tree[k].l==tree[k].r)
{
scanf("%d",&tree[k].w);
return;
}
int mid=(l+r)/2;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
//标记下传
inline void down(int k)
{
tree[k*2].f+=tree[k].f;
tree[k*2+1].f+=tree[k].f;
tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1);
tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1);
tree[k].f=0;
}
//单点查询
inline void ask_point(int k)
{
if(tree[k].l==tree[k].r)
{
ans=tree[k].w;
return ;
}
if(tree[k].f) down(k);
int mid=(tree[k].l+tree[k].r)/2;
if(x<=mid) ask_point(k*2);
else ask_point(k*2+1);
}
//单点修改
inline void change_point(int k)
{
if(tree[k].l==tree[k].r)
{
tree[k].w+=y;
return;
}
if(tree[k].f) down(k);
int mid=(tree[k].l+tree[k].r)/2;
if(x<=mid) change_point(k*2);
else change_point(k*2+1);
tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
//区间查询
inline void ask_interval(int k)
{
if(tree[k].l>=a&&tree[k].r<=b)
{
ans+=tree[k].w;
return;
}
if(tree[k].f) down(k);
int mid=(tree[k].l+tree[k].r)/2;
if(a<=mid) ask_interval(k*2);
if(b>mid) ask_interval(k*2+1);
}
//区间修改
inline void change_interval(int k)
{
if(tree[k].l>=a&&tree[k].r<=b)
{
tree[k].w+=(tree[k].r-tree[k].l+1)*y;
tree[k].f+=y;
return;
}
if(tree[k].f) down(k);
int mid=(tree[k].l+tree[k].r)/2;
if(a<=mid) change_interval(k*2);
if(b>mid) change_interval(k*2+1);
tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
int main()
{
scanf("%d",&n);//n个节点
build(1,1,n);//建树
scanf("%d",&m);//m种操作
for(int i=1;i<=m;i++)
{
scanf("%d",&p);
ans=0;
if(p==1)
{
scanf("%d",&x);
ask_point(1);//单点查询,输出第x个数
printf("%d",ans);
}
else if(p==2)
{
scanf("%d%d",&x,&y);
change_point(1);//单点修改
}
else if(p==3)
{
scanf("%d%d",&a,&b);//区间查询
ask_interval(1);
printf("%d\n",ans);
}
else
{
scanf("%d%d%d",&a,&b,&y);//区间修改
change_interval(1);
}
}
return 0;
}
HDU-1754 (区间最大值)
#include <bits/stdc++.h>
#define ll long long
#define Max 200002
using namespace std;
int n,p,a,b,m,x,y,ans,maxx;
struct node
{
int l,r,w,f;
}tree[Max<<2];
//标记下传
inline void down(int k)
{
/*
tree[k*2].f+=tree[k].f;
tree[k*2+1].f+=tree[k].f;
tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1);
tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1);
tree[k].f=0;
*/
tree[k].w=max(tree[k*2].w,tree[k*2+1].w);//最大值
}
//建树
inline void build(int k,int l,int r)
{
tree[k].l=l,tree[k].r=r;
if(tree[k].l==tree[k].r)
{
scanf("%d",&tree[k].w);
return;
}
int mid=(l+r)/2;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
down(k);
}
//单点修改
inline void change_point(int k)
{
if(tree[k].l==tree[k].r)
{
tree[k].w=y; //修改
// cout<<"_____> "<<k<<endl;
return;
}
int mid=(tree[k].l+tree[k].r)/2;
if(x<=mid) change_point(k*2);
else change_point(k*2+1);
down(k);
}
//区间最大值查询
inline int ask_max(int k,int ls,int rs){
if(tree[k].l==ls&&tree[k].r==rs){
return tree[k].w;
}
int mid=(tree[k].l+tree[k].r)>>1;
if(ls<=mid) maxx=max( maxx,ask_max(k*2, ls, min(mid,rs)) );
if(mid<rs) maxx=max( maxx,ask_max(k*2+1, max(mid+1,ls), rs) );
return maxx;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF){
build(1,1,n);
char op[10];
for(int i=0;i<m;i++){
ans=0;
maxx=-1;
scanf("%s",op);
if(op[0]=='Q'){
scanf("%d%d",&a,&b);
ans=ask_max(1,a,b);
printf("%d\n",ans);
}
if(op[0]=='U'){
scanf("%d%d",&x,&y);
change_point(1);
// cout<<"****-> "<<tree[5].w<<endl;
}
}
}
return 0;
}