2019徐州网络赛 I query 线段树 离线

题目链接:https://nanti.jisuanke.com/t/41391

题解:先找出每一对(pi​,pj​),那么i, j 记录为 区间[l, r],则查询就变为,在[L,R]内有多少区间,然后我们离线+线段树就可以搞定了,按照 r 排序,对应进行区间查询即可

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int pos[N];
int a[N];
int n, m;
vector<int> v[N];
struct node {
	int l, r;
	int val;
}tree[N << 2];
struct QUE {
	int l, r;
	int id;
}q[N];
int ans[N];
bool cmp1(QUE x, QUE y) {
	return x.r < y.r;
}
void build(int l, int r, int cur) {
	tree[cur].l = l;
	tree[cur].r = r;
	tree[cur].val = 0;
	if(l == r) return;
	int mid = (l + r) >> 1;
	build(l, mid, cur << 1);
	build(mid + 1, r, cur << 1 |1);
}
void update(int pos, int cur) {
	if(tree[cur].l == tree[cur].r) {
		tree[cur].val++;
		return;
	}
	if(pos <= tree[cur << 1].r) update(pos, cur <<1);
	else update(pos, cur << 1 |1);
	tree[cur].val = tree[cur << 1].val + tree[cur << 1 | 1].val;
}
int query(int pl, int pr, int cur) {
	if(pl <= tree[cur].l && tree[cur].r <= pr) {
		return tree[cur].val;
	}
	int res = 0;
	if(pl <= tree[cur << 1].r) res += query(pl, pr, cur << 1);
	if(pr >= tree[cur << 1 | 1].l) res += query(pl, pr, cur << 1 | 1);
	return res;
}
int main() {
	scanf("%d %d", &n, &m);
	for(int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
		pos[a[i]] = i;
	}
	int l, r;
	for(int i = 1; i <= n; i++) {
		for(int j = a[i] + a[i]; j <= n; j += a[i]) {
			l = i;
			r = pos[j];
			if(l > r) swap(l, r);
			v[r].push_back(l);
		}
	}
	for(int i = 1; i <= m; i++)
		scanf("%d %d", &q[i].l, &q[i].r), q[i].id = i;
	sort(q + 1, q+ 1 + m, cmp1);
	build(1, n, 1);
	for(int j = 1, i = 1; i <= n; i++) {
		for(int k = 0; k < v[i].size(); k++)
			update(v[i][k], 1);
		while(j <= m && q[j].r == i) {
			ans[q[j].id] = query(q[j].l, q[j].r, 1);
			j++;
		}
	}
	for(int i = 1; i <= m; i++)
		printf("%d\n", ans[i]);
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值