其他分享
首页 > 其他分享> > P3987 我永远喜欢珂朵莉~

P3987 我永远喜欢珂朵莉~

作者:互联网

题面

第一行两个数表示n,m

第二行n个非负整数表示ai

之后m行每行一个操作

1 l r x : 把区间[l,r]中所有x的倍数/x

2 l r : 查询区间[l,r]的和

1 <= n , m <= 100000

0 <= ai <= 500000

1 <= x <= 500000

思路

合理的树状数组优化暴力。

用vector维护余数,然后每次修改都暴力查询,然后暴力去掉余数。

既然能过
需要玄学卡常

代码

#include <bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;



long long read() {
	long long in = 0;
	short f = 1;
	char c = getchar();
	while (c > '9' || c < '0') {
		if (c == '-') f = -1;
		c = getchar();
		break;
	}
	while (c >= '0' && c <= '9') {
		in = in * 10 + c - '0';
		c = getchar();
	}
	return in * f;
}
void write(long long x) {
	if (x == 0) {
		putchar('0');
		return;
	}
	if (x < 0) {
		putchar('-');
		x = -x;
	}
	if (x < 10) {
		putchar(x + '0');
		return;
	}
	short num = 0;
	char c[30];
	while (x) c[++num] = (x % 10) + 48, x /= 10;
	while (num) putchar(c[num--]);
}

long long t[100005];
int n, m;
int a[100005];
long long qzh[100005];
vector<int> yushu[500005];
typedef vector<int>::iterator vit;
vector<vit> will_erase;

inline long long query(int p) {
	long long result = 0;
	for (; p; p -= lowbit(p)) {
		result += t[p];
	}
	return result;
}
inline void update(int p, long long v) {
	for (; p <= n; p += lowbit(p)) {
		t[p] += v;
	}
}


int main() {
	n = read();
	m = read();
	for (int i = 1; i <= n; i++) {
		a[i] = read();
		for (int j = 1; j * j <= a[i]; j++) {
			if (a[i] % j == 0) {
				yushu[j].push_back(i);
				if (a[i] != j * j) {
					yushu[a[i] / j].push_back(i);
				}
			}
		}
		update(i,a[i]);
	}
	while (m--) {
		short opt;
		opt = read();
		if (opt == 1) {
			int l = read(), r = read(), x = read();
			will_erase.clear();
			if (x == 1 || yushu[x].empty()) continue;
			vit l2 = lower_bound(yushu[x].begin(), yushu[x].end(), l);
			vit r2 = upper_bound(yushu[x].begin(), yushu[x].end(), r);
			if (l2 == yushu[x].end()) continue;
			for (vit it = l2; it != r2; it++) {
				if (a[*it] % x != 0) continue;
				update(*it, -(a[*it] - a[*it] / x));
				a[*it] /= x;
				if (a[*it] % x != 0) will_erase.push_back(it);
			}
			if (!will_erase.empty()) {
				for (int i = will_erase.size() - 1; i >= 0; i--) {
					yushu[x].erase(will_erase[i]);
				}
			}
		} else {
			int l, r;
			l = read();
			r = read();
			write(query(r) - query(l - 1));
			putchar('\n');
		}
	}
	return 0;
}

标签:vector,int,P3987,long,read,erase,朵莉,永远,query
来源: https://www.cnblogs.com/xiezheyuan/p/note-rem-p3987.html