树状数组、线段树板子

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#define ll long long
using namespace std;
const int maxx=100001;
int n,q;
ll c1[maxx],c2[maxx];
ll lowbit(ll x){return x&(-x);}
struct tree{
	void add(long long *array,int x,int val){
		for(int i=x;i<=n;i+=lowbit(i))
			array[i]+=val;
	}
	long long query(long long *array,int x){
		long long ans=0;
		for(int i=x;i;i-=lowbit(i))
			ans+=array[i];
		return ans;
	}
}tree;
ll read(){
	char x;
	while((x=getchar())<'0' || x>'9');
	ll u=x-'0';
	while((x=getchar())>='0' && x<='9')u=u*10+x-'0';
	return u;
	}
int main(){
#ifndef ONLINE_JUDGE
	freopen("input.in","r",stdin);
	freopen("output.out","w",stdout);
#endif
	int i,j,k,m,pre=0;
	n=read();q=read();
	for(i=1;i<=n;i++){
		k=read();
		tree.add(c1,i,k-pre);
		tree.add(c2,i,(k-pre)*(i-1));
		pre=k;
	}
	while(q--){
		k=read();
		if(k==1){
			i=read();
			j=read();
			m=read();
			tree.add(c1,i,m);
			tree.add(c1,j+1,-m);
			tree.add(c2,i,m*(i-1));
			tree.add(c2,j+1,-m*j);
		}
		else{
			i=read();
			j=read();
			ll dog=j*tree.query(c1,j)-tree.query(c2,j);
			ll sb=(i-1)*tree.query(c1,i-1)-tree.query(c2,i-1);
			printf("%lld\n",dog-sb);
		}
	}
return 0;
}
#include<cstdio>
#include<cstring>
#include<iostream>

#define ls node << 1
#define rs node << 1 | 1
#define maxn 100005
#define For(a, b, c) for(a = b; a <= (int)c; ++a)
using namespace std;
typedef long long LL;
int n, m;
LL tr[maxn << 2], plu[maxn << 2], mut[maxn << 2], p, a[maxn];

inline void push_up(int node){
	tr[node] = (tr[ls] + tr[rs]) % p;
}

void build(int node, int l, int r){
	mut[node] = 1;
	if(l == r){
		tr[node] = a[l];
		return ;
	}
	int mid = l + r >> 1;
	build(ls, l, mid);
	build(rs, mid + 1, r);
	push_up(node);
}

inline void add(int node, int l, int r, int x, bool d){
	if(!d){
		(mut[node] *= x) %= p;
		(tr[node] *= x) %= p;
		(plu[node] *= x) %= p;
	}
	else{
		(plu[node] += x) %= p;
		(tr[node] += (r - l + 1) * x) %= p;
	}
}

inline void push_down(int node, int l, int r){
	if(mut[node] == 1 && !plu[node]) return ;
	int mid = l + r >> 1;
	if(mut[node] != 1){
		(tr[ls] *= mut[node]) %= p;
		(mut[ls] *= mut[node]) %= p;
		(plu[ls] *= mut[node]) %= p;
		(tr[rs] *= mut[node]) %= p;
		(mut[rs] *= mut[node]) %= p;
		(plu[rs] *= mut[node]) %= p;
	} mut[node] = 1;
	if(plu[node]){
		(tr[ls] += (mid - l + 1) * plu[node]) %= p;
		(plu[ls] += plu[node]) %= p;
		(tr[rs] += (r - mid) * plu[node]) %= p;
		(plu[rs] += plu[node]) %= p;
	} plu[node] = 0;
}

void updata(int node, int l, int r, int z, int y, int x, bool d){
	if(l >= z && r <= y){
		add(node, l, r, x, d);
		return ;
	}
	push_down(node, l, r);
	int mid = l + r >> 1;
	if(y <= mid) updata(ls, l, mid, z, y, x, d);
	else if(z > mid) updata(rs, mid + 1, r, z, y, x, d);
	else{
		updata(ls, l, mid, z, y, x, d);
		updata(rs, mid + 1, r, z, y, x, d);
	}
	push_up(node);
}

LL query(int node, int l, int r, int z, int y){
	if(l >= z && r <= y) return tr[node];
	push_down(node, l, r);
	int mid = l + r >> 1;
	if(y <= mid) return query(ls, l, mid, z, y);
	else if(z > mid) return query(rs, mid + 1, r, z, y);
	return (query(ls, l, mid, z, y) + query(rs, mid + 1, r, z, y)) % p;
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("st.in", "r", stdin);
	freopen("st.out","w",stdout);
#endif
	int i, u, x, y, k;
	scanf("%d%d%lld", &n, &m, &p);
	For(i, 1, n) scanf("%lld", &a[i]);
	build(1, 1, n);
	while(m--){
		scanf("%d", &u);
		if(u == 1){
			scanf("%d%d%d", &x, &y, &k);
			updata(1, 1, n, x, y, k, 0);
		}
		else if(u == 2){
			scanf("%d%d%d", &x, &y, &k);
			updata(1, 1, n, x, y, k, 1);
		}
		else{
			scanf("%d%d", &x, &y);
			printf("%lld\n", query(1, 1, n, x, y));
		}
	}
	return 0;
}
#include<cstdio>
#include<cstring>
#include<iostream>

#define ls node << 1
#define rs node << 1 | 1
#define maxn 100005
#define For(a, b, c) for(a = b; a <= (int)c; ++a)
using namespace std;
typedef long long LL;
int n, m;
LL tr[maxn << 2], plu[maxn << 2], mut[maxn << 2], p, a[maxn];

inline void push_up(int node){
	tr[node] = (tr[ls] + tr[rs]) % p;
}

void build(int node, int l, int r){
	mut[node] = 1;
	if(l == r){
		tr[node] = a[l];
		return ;
	}
	int mid = l + r >> 1;
	build(ls, l, mid);
	build(rs, mid + 1, r);
	push_up(node);
}

inline void add(int node, int l, int r, int x, bool d){
	if(!d){
		(mut[node] *= x) %= p;
		(tr[node] *= x) %= p;
		(plu[node] *= x) %= p;
	}
	else{
		(plu[node] += x) %= p;
		(tr[node] += (r - l + 1) * x) %= p;
	}
}

inline void push_down(int node, int l, int r){
	if(mut[node] == 1 && !plu[node]) return ;
	int mid = l + r >> 1;
	if(mut[node] != 1){
		(tr[ls] *= mut[node]) %= p;
		(mut[ls] *= mut[node]) %= p;
		(plu[ls] *= mut[node]) %= p;
		(tr[rs] *= mut[node]) %= p;
		(mut[rs] *= mut[node]) %= p;
		(plu[rs] *= mut[node]) %= p;
	} mut[node] = 1;
	if(plu[node]){
		(tr[ls] += (mid - l + 1) * plu[node]) %= p;
		(plu[ls] += plu[node]) %= p;
		(tr[rs] += (r - mid) * plu[node]) %= p;
		(plu[rs] += plu[node]) %= p;
	} plu[node] = 0;
}

void updata(int node, int l, int r, int z, int y, int x, bool d){
	if(l >= z && r <= y){
		add(node, l, r, x, d);
		return ;
	}
	push_down(node, l, r);
	int mid = l + r >> 1;
	if(y <= mid) updata(ls, l, mid, z, y, x, d);
	else if(z > mid) updata(rs, mid + 1, r, z, y, x, d);
	else{
		updata(ls, l, mid, z, y, x, d);
		updata(rs, mid + 1, r, z, y, x, d);
	}
	push_up(node);
}

LL query(int node, int l, int r, int z, int y){
	if(l >= z && r <= y) return tr[node];
	push_down(node, l, r);
	int mid = l + r >> 1;
	if(y <= mid) return query(ls, l, mid, z, y);
	else if(z > mid) return query(rs, mid + 1, r, z, y);
	return (query(ls, l, mid, z, y) + query(rs, mid + 1, r, z, y)) % p;
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("st.in", "r", stdin);
	freopen("st.out","w",stdout);
#endif
	int i, u, x, y, k;
	scanf("%d%d%lld", &n, &m, &p);
	For(i, 1, n) scanf("%lld", &a[i]);
	build(1, 1, n);
	while(m--){
		scanf("%d", &u);
		if(u == 1){
			scanf("%d%d%d", &x, &y, &k);
			updata(1, 1, n, x, y, k, 0);
		}
		else if(u == 2){
			scanf("%d%d%d", &x, &y, &k);
			updata(1, 1, n, x, y, k, 1);
		}
		else{
			scanf("%d%d", &x, &y);
			printf("%lld\n", query(1, 1, n, x, y));
		}
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值