题目:给一个长度为n的序列a[1],...,a[n]和n个贡献参数w[1],...,w[n]。 每次提问[l,r],如果权值为x的数出现了k次,则对答案贡献x*w[k],没出现过的数对答案不做贡献,求答案。
蒟蒻感觉莫队没问题,是否是离散化出问题了?
#include<bits/stdc++.h>
using namespace std;
#define M 2000000 + 10
#define int long long
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define fr(i,j,k) for(int i=j;i<=k;i++)
#define rs(i,j,k) for(int i=j;i>=k;i--)
#define endl '\n'
#define IOS ios::sync_with_stdio(0)
#define pb(i) push_back(i)
#define pf(i) push_front(i)
#define mem(a,b) memset(a,b,sizeof a)
struct node {
int l, r, id;
} ask[M];
int n, q, m, tot;
int a[M], w[M], cnt[100000000 + 10], ans[M], anss[M], bel[M];
map<int, int> d;
int hs[M];
int res;
void del(int x) {
tot -= a[x] * w[cnt[hs[x]]];
cnt[hs[x]]--;
tot += a[x] * w[cnt[hs[x]]];
}
void add(int x) {
tot -= a[x] * w[cnt[hs[x]]];
cnt[hs[x]] ++;
tot += a[x] * w[cnt[hs[x]]];
}
bool cmp(node a, node b) {
if (bel[a.l] == bel[b.l])return a.r < b.r;
return bel[a.l] < bel[b.l];
}
signed main() {
IOS;
cin >> n >> q;
int s = (int)sqrt(n), p = 1;
fr(i, 1, n) {
bel[i] = p;
cin >> a[i];
if (!d[a[i]]) {
hs[i] = ++res;
d[a[i]] = res;
}
if (i % s == 0) p++;
}
fr(i, 1, n) {
cin >> w[i];
}
fr(i, 1, q) {
cin >> ask[i].l >> ask[i].r;
ask[i].id = i;
}
sort(ask + 1, ask + 1 + q, cmp);
int l = 1, r = 0;
fr(i, 1, q) {
while (r < ask[i].r) add(++r);
while (r > ask[i].r) del(r--);
while (l < ask[i].l) del(l++);
while (l > ask[i].l) add(--l);
ans[ask[i].id] = tot;
}
fr(i, 1, q) {
cout << ans[i] << endl;
}
return 0;
}
//时间轴