WOJ 2790「雅礼集训 2017 Day1」市场

描述

image

输入

第一行为两个空格隔开的整数 n,q 分别表示商贩个数和政令 + 询问个数。

第二行包含 n 个由空格隔开的整数 a0∼an−1

接下来 q 行,每行表示一个操作,第一个数表示操作编号 1∼4 ,接下来的输入和问题描述一致。

输出

对于每个 3、4 操作,输出询问答案。

样例输入

10 10
-5 -4 -3 -2 -1 0 1 2 3 4
1 0 4 1
1 5 9 1
2 0 9 3
3 0 9
4 0 9
3 0 1
4 2 3
3 4 5
4 6 7
3 8 9

样例输出

-2
-2
-2
-2
0
1
1

提示

数据范围与提示

对于 30%的数据,\(n,q≤10^3\)

对于 60% 的数据,保证数据随机;

对于 100%的数据,\(1≤n,q≤10^5,0≤l≤r≤n−1,c∈[−10^4,10^4],d∈[2,10^9]\)

题解

学长讲了加看题解才大概懂了
\(min\)\(sum\)是模板,对于除法,维护一个\(min\)\(max\),当\(max/k==min/k\)时,对于整个区间就相当于减去了\(max-max/k\),然后打一个减的\(lazy\)即可

代码

#include<bits/stdc++.h>
#define N 100010
#define lc (p<<1)
#define rc (p<<1|1)
#define int long long
#define INF 0x7fffffffffffffff
#define in read()
using namespace std;
inline int read()
{
    int data=0;int w=1; char ch=getchar();
    while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
    if(ch=='-') w=-1,ch=getchar();
    while(ch>='0' && ch<='9') data=(data<<3)+(data<<1)+ch-'0',ch=getchar();
    return data*w;
}

int n, q, a[N];
int opt, x, y, z;
inline int divide(int x, int y) {
	return floor((double)x/y);
}
struct Node {
	int l,r,ly,sum,mx,mn;
} t[N<<2];
inline void pushup(int p) {
	t[p].sum=t[lc].sum+t[rc].sum;
	t[p].mx=max(t[lc].mx, t[rc].mx);
	t[p].mn=min(t[lc].mn, t[rc].mn);
}
inline void pushnow(int p, int val) {
	t[p].mx+=val;t[p].mn+=val;
	t[p].ly+=val;t[p].sum+=(t[p].r-t[p].l+1)*val;
}
inline void pushdown(int p) {
	if(!t[p].ly) return ; 
	pushnow(lc, t[p].ly);pushnow(rc, t[p].ly);
	t[p].ly=0;
}
inline void build(int p, int l, int r) {
	t[p].l=l; t[p].r=r;
	if(l==r) {t[p].mx=t[p].mn=a[l]=t[p].sum=a[l];t[p].ly=0;return ;}
	int mid=(l+r)>>1;
	build(lc, l, mid);build(rc, mid+1, r);
	pushup(p);
}
inline void update_add(int p, int ql, int qr, int val) {
	if(ql<=t[p].l && t[p].r<=qr) {pushnow(p, val);return ;}
	int mid=(t[p].l+t[p].r)>>1;pushdown(p);
	if(ql<=mid) update_add(lc, ql, qr, val);
	if(qr> mid) update_add(rc, ql, qr, val);
	pushup(p);
}
inline void update_div(int p, int ql, int qr, int val) {
	if(ql<=t[p].l && t[p].r<=qr) {
		int chg1=divide(t[p].mn, val)-t[p].mn;
		int chg2=divide(t[p].mx, val)-t[p].mx;
		if(chg1==chg2) {pushnow(p, chg1);return ;}
	}
	int mid=(t[p].l+t[p].r)>>1;pushdown(p);
	if(ql<=mid) update_div(lc, ql, qr, val);
	if(qr> mid) update_div(rc, ql, qr, val);
	pushup(p);
}
inline int query_min(int p, int ql, int qr) {
	if(ql<=t[p].l && t[p].r<=qr) return t[p].mn;
	int mid=(t[p].l+t[p].r)>>1,ans=INF; pushdown(p);
	if(ql<=mid) ans=min(ans, query_min(lc, ql, qr));
	if(qr> mid) ans=min(ans, query_min(rc, ql, qr));
	return ans;
}
inline int query_sum(int p, int ql, int qr) {
	if(ql<=t[p].l && t[p].r<=qr) return t[p].sum;
	int mid=(t[p].l+t[p].r)>>1,ans=0; pushdown(p);
	if(ql<=mid) ans+=query_sum(lc, ql, qr);
	if(qr> mid) ans+=query_sum(rc, ql, qr);
	return ans;
}
signed main() {
	n=in,q=in;
	for(int i=1;i<=n;i++) a[i]=in;
	build(1,1,n);
	while(q--){
		int op=in,l=in+1,r=in+1;
		switch(op){
			case 1:update_add(1,l,r,in);break;
			case 2:update_div(1,l,r,in);break;
			case 3:printf("%lld\n",query_min(1,l,r));break;
			case 4:printf("%lld\n",query_sum(1,l,r));break;
		}
	}
	return 0;
}
posted @ 2021-08-05 09:06  Socratize  阅读(43)  评论(0)    收藏  举报