按照习惯,这里只是对我这几天所写的线段树题目的总结
hdu 1166 排兵布阵
点增减
#include<cstdio>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=55555;
int sum[maxn<<2];
void push(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l,int r,int rt)
{
if(l==r)
{
scanf("%d",&sum[rt]);
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
push(rt);
}
void update(int p,int add,int l,int r,int rt)
{
if(l==r)
{
sum[rt]+=add;
return;
}
int m=(l+r)>>1;
if(p<=m)update(p,add,lson);
else update(p,add,rson);
push(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)return sum[rt];
int m=(l+r)>>1;
int ret=0;
if(L<=m)ret+=query(L,R,lson);
if(R>m)ret+=query(L,R,rson);
return ret;
}
int main()
{
int t,n;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
printf("Case %d:\n",i);
scanf("%d",&n);
build(1,n,1);
char op[10];
while(scanf("%s",op))
{
if(op[0]=='E')break;
int a,b;
scanf("%d%d",&a,&b);
if(op[0]=='Q')printf("%d\n",query(a,b,1,n,1));
else
if(op[0]=='S')update(a,-b,1,n,1);
else update(a,b,1,n,1);
}
}
return 0;
}
hdu 1754
点替换
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 200010;
int max(int a,int b){return a > b ? a : b;}
int maxn[N * 4];
int n,m,a,b;
void build(int o,int l,int r)
{
if(l == r){ scanf("%d",&maxn[o]);return;}
int mid = (l + r) >> 1;
build(o << 1,l,mid);
build(o << 1 | 1,mid + 1,r);
maxn[o] = max(maxn[o << 1],maxn[o << 1 | 1]);
}
int query(int o,int l,int r)
{
int mid =(l + r) >> 1;
if(a <= l && b >= r) return maxn[o];
int ans = -1;
if(a <= mid) ans = max(ans,query(o << 1,l,mid));
if(b > mid) ans = max(ans,query(o << 1 | 1,mid+1,r));
return ans;
}
void update(int o,int l,int r)
{
if(l == r){ maxn[o] = b; return; }
int mid = (l + r) >> 1;
if(a <= mid) update(o << 1,l,mid); else update(o << 1 | 1,mid+1,r);
maxn[o] = max(maxn[o << 1],maxn[o << 1 | 1]);
}
int main()
{
char c[2];
while(scanf("%d%d",&n,&m)!=EOF && n && m)
{
build(1,1,n);
for(int i = 1;i <= m; i++)
{
scanf("%s",c);
if(c[0] == 'Q')
{
scanf("%d%d",&a,&b);
printf("%d\n",query(1,1,n));
}
else
{
scanf("%d%d",&a,&b);
update(1,1,n);
}
}
}
return 0;
}
hdu 1698
段替换
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define fill(a,x) memset(a,x,sizeof(a))
#define lson o << 1
#define rson o << 1 | 1
const int N = 100010;
int setv[N << 2],sum[N << 2];
int n,m,ll,rr,v;
void build(int o,int l,int r)
{
if(l == r){sum[o] = 1;return;}
int mid = (l+r)/2;
build(lson,l,mid);
build(rson,mid+1,r);
sum[o] = sum[lson] + sum[rson];
}
void pushdown(int o,int l,int r)
{
if(setv[o] > 0)
{
setv[lson] = setv[rson] = setv[o];
int mid = (l+r) >> 1;
sum[lson] = setv[o] * (mid-l+1);
sum[rson] = setv[o] * (r-mid);
setv[o] = 0;
}
return;
}
void update(int o,int l,int r)
{
if(ll <= l && rr >= r) {setv[o] = v;sum[o] = v * (r-l+1);}
else
{
pushdown(o,l,r);
int mid = (l+r) >> 1;
if(ll <= mid) update(lson,l,mid);
if(rr > mid) update(rson,mid+1,r);
sum[o] = sum[lson] + sum[rson];
}
}
int main()
{
int t;
scanf("%d",&t);
for(int kase = 1;kase <= t;kase ++)
{
scanf("%d%d",&n,&m);
build(1,1,n);
fill(setv,0);
for(int i = 1;i <= m; i++)
{
scanf("%d%d%d",&ll,&rr,&v);
update(1,1,n);
}
printf("Case %d: The total value of the hook is %d.\n",kase,sum[1]);
}
return 0;
}
bzoj 1798
较难,区间乘与加的混合,注意使用分配率
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define dep(i,x,y) for(int i=x;i>=y;i--)
#define fill(a,x) memset(a,x,sizeof(a))
typedef long long LL;
const int N = 100010;
struct node{
LL add,mul,sum;
}seq[N * 4];
LL ll,rr,Add,Mul,mod,n,m;
void build(int o,int l,int r)
{
seq[o].mul = 1;seq[o].add = 0;
if(l == r){ cin >> seq[o].sum; return; }
int mid = (l + r) / 2;
build(o*2, l, mid);
build(o*2+1, mid+1, r);
seq[o].sum = (seq[o*2].sum + seq[o*2+1].sum) % mod;
return;
}
inline void refresh(int o,int l,int r)
{
int lc = o*2,rc = o*2+1,mid = (l+r)/2;
seq[lc].sum = (seq[lc].sum * seq[o].mul + seq[o].add * (mid-l+1)) % mod;
seq[lc].mul = (seq[lc].mul * seq[o].mul) % mod;
seq[lc].add = (seq[lc].add * seq[o].mul + seq[o].add) % mod;
seq[rc].sum = (seq[rc].sum * seq[o].mul + seq[o].add * (r - mid)) % mod;
seq[rc].mul = (seq[rc].mul * seq[o].mul) % mod;
seq[rc].add = (seq[rc].add * seq[o].mul + seq[o].add) % mod;
seq[o].mul = 1;seq[o].add = 0;
return;
}
void update(int o,int l,int r)
{
if(rr < l || ll > r) return;
if(ll <= l && rr >= r)
{
seq[o].sum = (seq[o].sum * Mul + (r - l +1) * Add) % mod;
seq[o].add = (seq[o].add * Mul + Add) % mod;
seq[o].mul = seq[o].mul * Mul % mod;
return;
}
int mid = (l+r)/2;
refresh(o,l,r);
update(o*2,l,mid);
update(o*2+1,mid+1,r);
seq[o].sum = (seq[o*2].sum + seq[o*2+1].sum) % mod;
}
LL query(int o,int l,int r)
{
if (rr < l || r < ll) return 0;
if (ll <= l && r <= rr) return seq[o].sum;
int mid = (l+r)/2;
refresh(o,l,r);
LL res = (query(o*2,l,mid) + query(o*2+1,mid+1,r)) % mod;
seq[o].sum = (seq[o*2].sum + seq[o*2+1].sum) % mod;
return res;
}
int main()
{
scanf("%lld%lld",&n,&mod);
build(1,1,n);
scanf("%lld",&m);
LL x;
rep(i,1,m)
{
scanf("%lld%lld%lld",&x,&ll,&rr);
if(x == 1){scanf("%lld",&Mul); Add = 0;update(1,1,n);}
else
if(x == 2){scanf("%lld",&Add); Mul = 1;update(1,1,n);}
else printf("%lld\n",query(1,1,n));
}
return 0;
}
poj 3468
段增减
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson o << 1
#define rson o << 1 | 1
typedef long long LL;
const int N = 100010;
LL add[N << 2],sum[N << 2],v;
int n,m,ll,rr;
void build(int o,int l,int r)
{
add[o] = 0;
if(l == r){scanf("%lld",&sum[o]);return;}
int mid = (l+r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
sum[o] = sum[rson] + sum[lson];
}
void pushdown(int o,int l,int r)
{
if(add[o])
{
int mid = (l+r)>>1;
add[lson] += add[o];
add[rson] += add[o];
sum[lson] += add[o] * (mid-l+1);
sum[rson] += add[o] * (r-mid);
add[o] = 0;
}
}
void update(int o,int l,int r)
{
if(ll <= l && rr >= r)
{
add[o] += v;
sum[o] += v * (r-l+1);
return;
}
pushdown(o,l,r);
int mid = (l+r)>>1;
if(ll <= mid)update(lson,l,mid);
if(rr > mid) update(rson,mid+1,r);
sum[o] = sum[lson] + sum[rson];
}
LL query(int o,int l,int r)
{
if(ll <= l && rr >= r) return sum[o];
int mid = (l+r) >> 1;
pushdown(o,l,r);
LL ans = 0;
if(ll <= mid) ans += query(lson,l,mid);
if(rr > mid) ans += query(rson,mid+1,r);
return ans;
}
int main()
{
char c[2];
scanf("%d%d",&n,&m);
build(1,1,n);
for(int i = 1;i <= m; i++)
{
scanf("%s",c);
scanf("%d%d",&ll,&rr);
if(c[0] == 'C')
{
scanf("%lld",&v);
update(1,1,n);
}
else printf("%lld\n",query(1,1,n));
}
return 0;
}