板子
#include<iostream>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<map>
#include<vector>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<ctime>
using namespace std;
#define rep(i,aa,bb) for(register int i=aa;i<=bb;i++)
#define rrep(i,aa,bb) for(register int i=aa;i>=bb;i--)
#define mset(var,val) memset(var,val,sizeof(var))
#define LL long long
#define eps 0.000001
#define inf 0x7f7f7f7f
#define llinf 1e18
#define exp 0.000001
#define pai 3.141592654
#define random(x) rand()%(x)
#define lowbit(x) x&(-x)
inline int read()
{
int x=0,y=1;char a=getchar();while ( a>'9' || a<'0'){if ( a=='-')y=-1;a=getchar();}
while ( a>='0' && a<='9' ){ x=(x<<3)+(x<<1)+a-'0'; a=getchar();}return x*y;
}
#define N 1000009
using namespace std;
#ifdef WIN32
#define LL "%I64d\n"
#else
#define LL "%lld\n"
#endif
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
區間加,區間詢問
(luogu線段樹模板1)
long long sum[N<<2|1],add[N<<2|1]={0};
inline void update(int rt){
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
inline void build(int l,int r,int rt)
{
if ( l==r )
{
sum[rt]=read();
add[rt]=0;
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
update(rt);
}
inline void color (int l,int r,int rt,int v)
{
sum[rt]+=(r-l+1)*v;
add[rt]+=v;
}
inline void push_col(int l,int r,int rt)
{
if ( add[rt] )
{
int m=(l+r)>>1;
color(lson,add[rt]);
color(rson,add[rt]);
add[rt]=0;
return ;
}
}
inline void modify(int l,int r,int rt,int nowl,int nowr,int v)
{
if ( nowl <= l && r <= nowr )
{
color(l,r,rt,v);
return ;
}
int m=(l+r)>>1;
push_col(l,r,rt);
if ( nowl <= m )
modify(lson,nowl,nowr,v);
if ( nowr >= m+1)
modify(rson,nowl,nowr,v);
update(rt);
}
inline long long query(int l,int r,int rt,int quel,int quer)
{
if( quel<=l && r<=quer)
{
return sum[rt];
}
push_col(l,r,rt);
long long ans=0;
int m=(l+r)>>1;
if ( quel <= m)
ans+=query(lson,quel,quer);
if ( quer>=m+1)
ans+=query(rson,quel,quer);
return ans;
}
int main()
{
int n,m;
n=read(); m=read();
build(1,n,1);
while ( m-- )
{
int cmd=read();
if ( cmd==1 )
{
int x,y,k;
x=read();y=read();k=read();
modify(1,n,1,x,y,k);
}
else {
int x,y;
x=read();y=read();
printf(LL,query(1,n,1,x,y));
}
}
return 0;
}
區間加,區間乘,區間模,區間詢問
(luogu線段樹模二)
long long sum[N<<2|1],add[N<<2|1],mul[N<<2|1];
long long P;
void update(int rt )
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1] ; sum[rt]%=P;
}
void color(int l,int r,int rt,int a,int b)
{
sum[rt] = ( sum[rt]*a )%P + (long long)(r-l+1)*b; sum[rt]%=P;
add[rt] = (add[rt]*a+b)%P;
mul[rt] = (mul[rt]*a)%P;
}
void push_col(int l,int r,int rt)
{
if ( mul[ rt ] != 1 || add[rt] != 0 )
{
int m = ( l+r )>>1;
color(lson , mul[rt] , add[rt]);
color(rson , mul[rt] , add[rt]);
add[rt] = 0;
mul[rt] = 1;
}
}
void build(int l,int r,int rt)
{
add[rt] = 0 ;
mul[rt] = 1;
if ( l == r )
{
scanf("%d",&sum[rt]);
return ;
}
int m =( l+r ) >>1;
build( lson ) ; build( rson );
update(rt);
}
void modify(int l,int r,int rt,int nowl,int nowr,int a,int b){
if(nowl <= l && r <= nowr){
color(l,r,rt,a,b);
return;
}
push_col(l,r,rt);
int m = (l+r)>>1;
if(nowl <= m)modify(lson,nowl,nowr,a,b);
if(m < nowr)modify(rson,nowl,nowr,a,b);
update(rt);
}
long long query(int l,int r,int rt,int quel,int quer)
{
if( quel <= l && r <= quer ) return sum[rt];
push_col(l,r,rt);
int m = ( l+r ) >>1;
long long ans = 0;
if ( quel <= m ) ans += query(lson , quel , quer )%P ;
if ( m < quer ) ans += query(rson , quel , quer )%P ;
return ans%P;
}
int main()
{
int n , m;
scanf("%d%d%lld",&n,&m,&P);
build( 1 , n , 1 );
while ( m-- )
{
int cmd;
scanf("%d",&cmd);
if( cmd != 3 )
{
int x, y , k;
scanf("%d%d%d",&x,&y,&k);
if ( cmd == 1 ) modify( 1, n, 1, x, y , k , 0 );
else modify( 1, n, 1, x, y , 1 , k );
}
else {
int l ,r ;
scanf("%d%d",&l,&r);
printf("%d\n",query(1,n,1,l,r));
}
}
}
區間和,單點修改1
codevs 線段樹練習(1080)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct rode
{
int l;
int r;
int sum;
};
struct rode t[400001];
int n,m;
int a[100001];
void build(int left,int right,int k)
{
int mid =( left + right ) / 2;
if ( left == right )
{
t[k].l = left, t[k].r = right, t[k].sum = 0 ;
return ;
}
t[k].l = left; t[k].r = right; t[k].sum = 0;
build(left,mid,k*2); build(mid+1,right,k*2+1);
}
void insert(int n,int d,int k)
{
int mid = ( t[k].l + t[k].r ) / 2 ;
if ( t[k].l == t[k].r && d == t[k].r)
{
t[k].sum += n; return ;
}
if(d<=mid) insert(n,d,k*2);
else if ( d > mid) insert(n,d,k*2+1);
t[k].sum = t[k*2].sum + t[k*2+1].sum;
}
int search(int l,int r,int k)
{
int mid;
if(t[k].l==l&&t[k].r==r) return t[k].sum;
mid=(t[k].l+t[k].r)/2;
if(r<=mid) return search(l,r,k*2);
else if(l>mid) return search(l,r,k*2+1);
else return search(l,mid,k*2)+search(mid+1,r,k*2+1);
}
int main()
{
scanf("%d",&n);
build(1,n,1);
for (int i = 1; i <= n; i++)
scanf("%d",&a[i]),
insert(a[i],i,1);
scanf("%d",&m);
for (int i = 1; i <= m; i++)
{
int f,x,y;
scanf("%d%d%d",&f,&x,&y);
if ( f == 1 ) insert(y,x,1);
if ( f == 2 ) printf("%d\n",search(x,y,1));
}
return 0;
}
區間和,單點修改
codevs 線段樹練習(1081)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<deque>
using namespace std;
const int maxn = 100000;
int a[10000]={0};
struct node {
int l,r,d;
}tree[maxn*4+5];
int ans = 0;
void make_tree(int l,int r,int k){
tree[k].l = l; tree[k].r = r; tree[k].d = 0;
if ( l == r ) return ;
int mid = (l+r)>>1;
make_tree(l,mid,k<<1); make_tree(mid+1,r,k*2+1);
}
void make(int l,int r,int d,int k){
if ( r<tree[k].l || tree[k].r < l) return ;
if ( l <= tree[k].l && tree[k].r <= r ){
tree[k].d += d; return ;
}
make(l,r,d,k*2); make(l,r,d,k*2+1);
}
void ask(int k,int count){
if ( count<tree[k].l || count>tree[k].r ) return ;
ans += tree[k].d;
ask(k*2,count); ask(k*2+1,count);
}
int main(){
int n , m;
cin>>n;
for ( int i = 1 ; i <= n; i++)
scanf("%d",&a[i]);
make_tree(1,n,1);
cin>>m;
for ( int i = 1; i <= m; i++)
{
ans = 0;
int l,r,v,f;
cin>>f;
if ( f == 1 ){
scanf("%d%d%d",&l,&r,&v);
make(l,r,v,1);
}
else {
scanf("%d",&v);
ask(1,v);
printf("%d\n",ans+a[v]);
}
}
return 0;
}
區間和,單點修改
codevs 線段樹練習(1082)
#include<bits/stdc++.h>
using namespace std;
const int maxn=200011*4+9;
const int maxm=200100;
#define LL long long
struct Po{
LL sum,ad,l,r;
}tree[maxn];
long long nu[maxm];
long long n;
void push_up(LL k){
tree[k].sum = tree[k<<1].sum + tree[k<<1|1].sum;
}
void build(long long l,long long r,long long k)
{
tree[k].l = l; tree[k].r = r; tree[k].sum=0; tree[k].ad = 0;
if(l==r)
{
tree[k].sum = nu[l];
return;
}
int mid=(l+r)/2;
build(l,mid,k*2);
build(mid+1,r,k*2+1);
push_up(k);
}
void push_down(LL k,LL x,LL y){
if ( tree[k].ad){
tree[k<<1].ad += tree[k].ad;
tree[k<<1|1].ad += tree[k].ad;
tree[k<<1].sum += tree[k].ad*x;
tree[k<<1|1].sum += tree[k].ad*y;
tree[k].ad = 0;
}
}
void add(LL st,LL ed,LL v,long long k)
{
if ( ed < tree[k].l || st > tree[k].r ) return ;
long long mid=(tree[k].l+tree[k].r)/2;
if(tree[k].l>=st&&ed>=tree[k].r)
{
tree[k].sum += v*(tree[k].r-tree[k].l+1);
tree[k].ad += v;
return;
}
push_down(k,mid-tree[k].l+1,tree[k].r-mid);
if(st<=mid) add(st,ed,v,2*k);
if(ed>mid) add(st,ed,v,2*k+1);
push_up(k);
}
LL fin(LL st,LL ed,LL k){
if ( st > tree[k].r || ed < tree[k].l ) return 0;
if ( st <= tree[k].l&& tree[k].r<= ed ) return tree[k].sum;
LL mid = (tree[k].r+tree[k].l)>>1;
push_down(k,mid-tree[k].l+1,tree[k].r-mid);
LL ans = 0;
if ( st <= mid ) ans += fin(st,ed,k<<1);
if ( ed > mid ) ans += fin(st,ed,k<<1|1);
return ans;
}
int main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++) scanf("%lld",&nu[i]);
build(1,n,1);
long long m,flag,l,r,v;
scanf("%lld",&m);
for(int i=1;i<=m;i++)
{
scanf("%lld",&flag);
if(flag==1)
{
scanf("%lld %lld %lld",&l,&r,&v);
add(l,r,v,1);
}
if(flag==2)
{
scanf("%lld %lld",&l,&r);
printf("%lld\n",fin(l,r,1));
}
}
}
區間加,詢問區間內能被7整除的數字
codevs 線段樹練習(4919)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL inf=0x3f3f3f3f3f3f3f3fLL;
const int maxn=1e5+10;
int n,q,c[maxn],a,b,x,temp[7];
string str;
struct Node{
int l,r,add,mod[7];
} tree[maxn<<2];
void pushup(int pos)
{
for(int i=0;i<7;i++)
tree[pos].mod[i]=tree[ pos<<1 ].mod[i]+tree[ pos<<1|1 ].mod[i];
}
void build(int pos,int l,int r){
tree[pos].l = l; tree[pos].r = r; tree[pos].add = 0;
if ( tree[pos].l == tree[pos].r ){
tree[pos].mod[ c[l]%7 ] = 1;
return ;
}
int mid = ( l + r ) >> 1;
build(pos<<1,l,mid); build(pos<<1|1,mid+1,r);
pushup(pos);
}
void change(int pos,int x){
for ( int i = 0; i <= 6; i++) temp[ (i+x)%7 ] = tree[pos].mod[i];
for ( int i = 0; i <= 6; i++) tree[pos].mod[i] = temp[i];
}
void pushdown(int pos){
if ( tree[pos].l == tree[pos].r ) return ;
if ( tree[pos].add == 0 ) return ;
tree[pos<<1].add += tree[pos].add;
tree[pos<<1|1].add += tree[pos].add;
change(pos<<1,tree[pos].add); change(pos<<1|1,tree[pos].add);
tree[pos].add = 0;
}
void update(int pos,int st,int ed,int x){
if ( ed < tree[pos].l || st > tree[pos].r ) return ;
if ( st <= tree[pos].l && tree[pos].r <= ed){
tree[pos].add += x; change(pos,x); return ;
}
pushdown(pos);
int mid = (tree[pos].l+tree[pos].r)>>1;
if ( st <= mid ) update(pos<<1,st,ed,x);
if ( ed > mid ) update(pos<<1|1,st,ed,x);
pushup(pos);
}
int query(int pos,int l,int r)
{
pushdown(pos);
if(tree[pos].l>=l&&tree[pos].r<=r) return tree[pos].mod[0];
int mid=(tree[pos].l+tree[pos].r)>>1;
int ans = 0;
if(l<=mid) ans += query(pos<<1,l,r);
if(r> mid) ans += query(pos<<1|1,l,r);
return ans;
}
int main(){
std::ios::sync_with_stdio(false);
cin>>n;
for ( int i = 1; i <= n; i++) cin>>c[i];
build(1,1,n);
cin>>q;
while ( q-- ){
cin>>str;
if ( str[0] == 'a'){
cin>>a>>b>>x;
update(1,a,b,x);
}
if ( str[0] == 'c'){
cin>>a>>b;
cout<<query(1,a,b)<<endl;
}
}
return 0;
}