1. 程式人生 > 其它 >21.09.13模擬賽 魔法傳輸

21.09.13模擬賽 魔法傳輸

給區間L ~ R加上依次加上1 ~ R-L+1的值
可以差分解決,原數a_i用字首和sum_i的值表示,那麼每次在字首和陣列區間加,再差分即可

#include<iostream>
#include<cstdio>
#define rep(i,j,k) for(register int i(j);i<=k;++i)
#define drp(i,j,k) for(register int i(j);i>=k;--i)
#define bug cout<<"~~~~~~~~~~~~~"<<'\n';
#define bugout(x) cout<<x<<endl;
typedef long long lxl;
template<typename T>
inline T  max(T &a, T &b) {
	return a > b ? a : b;
}
template<typename T>
inline T  min(T &a, T &b) {
	return a < b ? a : b;
}

inline char gt() {
	static char buf[1 << 21], *p1 = buf, *p2 = buf;
	return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
template <typename T>
inline void  read(T &x) {
	register char ch = gt();
	x = 0;
	int w(0);
	while(!(ch >= '0' && ch <= '9'))w |= ch == '-', ch = gt();
	while(ch >= '0' && ch <= '9')x = x * 10 + (ch & 15), ch = gt();
	w ? x = ~(x - 1) : x;
}
template <typename T>
inline void out(T x, char cc) {
	if(x < 0) x = -x, putchar('-');
	char ch[20];
	int num(0);
	while(x || !num) ch[++num] = x % 10 + '0', x /= 10;
	while(num) putchar(ch[num--]);
	putchar(cc);
}
int n, m, x;
char op;
const int N = 1e5 + 79;
struct SegmentTree {
	int cnt, rt;
	lxl data[N << 2], tag[N << 2];
	int lc[N << 2], rc[N << 2];

	inline void pushdown(int p, int L, int R) {
		if(!tag[p]) return ;
		if(!lc[p]) lc[p] = ++cnt;
		if(!rc[p]) rc[p] = ++cnt;

		int mid((L+R) >> 1);

		data[lc[p]] += 1ll*(mid - L + 1) * tag[p];
		data[rc[p]] += 1ll*(R - mid) * tag[p];

		tag[lc[p]] += tag[p];
		tag[rc[p]] += tag[p];
		tag[p] = 0;
	}

	inline void insert(int &p, int L, int R, int ll, int rr, int val) {
		if(!p) p = ++cnt;
		if(ll <= L && rr >= R) {
			data[p] += 1ll * (R - L + 1) * val;
			tag[p] += val;
			return ;
		}
		pushdown(p, L, R);
		int mid(L + R >> 1);
		if(ll <= mid) insert(lc[p], L, mid, ll, rr, val);
		if(rr > mid) insert(rc[p], mid + 1, R, ll, rr, val);
		data[p] = data[lc[p]] + data[rc[p]];
	}

	inline lxl query(int p, int L, int R, int ll, int rr) {
		if(!p) return 0;
		if(ll <= L && rr >= R) return data[p];
		pushdown(p,L,R);
		int mid(L + R >> 1);
		lxl ans(0);
		if(ll <= mid) ans += query(lc[p], L, mid, ll, rr);
		if(rr > mid) ans += query(rc[p], mid + 1, R, ll, rr);
		return ans;
	}
} S;

int main() {
	freopen("score.in", "r", stdin);
	freopen("score.out", "w", stdout);
	read(n);
	read(m);
	int x, y;
	rep(i, 1, m) {
		op = gt();
		while(op != 'C' && op != 'Q') op = gt();
		if(op == 'Q') {
			read(x);
			out(S.query(S.rt, 1, n, 1, x),'\n');
		}
		else {
			read(x);read(y);
			S.insert(S.rt,1,n,x,y,1);
			S.insert(S.rt,1,n,y+1,y+1,-(y-x+1));
		}
	}

	return 0;
}

本文來自部落格園,作者:{2519},轉載請註明原文連結:https://www.cnblogs.com/QQ2519/p/15376085.html