这题真有意思,做了我一年,求助了jiangly神,终于AC了 总体就是按r,l顺序排序 用线段树维护颜色权值区间和
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<algorithm>
#include<deque>
#include<set>
#include<map>
#include<queue>
#include<math.h>
#include<unordered_set>
#include<unordered_map>
#include<numeric>
#include<stack>
#include<functional>
#include<cstring>
#include<sstream>
#pragma warning(disable:4996)
using namespace std;
#define pb push_back
#define fi first
#define _for(i,a,b) for(int i=(a);i<(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
#define inf 0x7fffffff
#define ll long long
#define ull unsigned long long
#define endl "\n"
template<typename T>
ostream& operator<<(ostream & os, const vector<T>&v)
{
for (int i = 0; i < v.size(); i++)
os << v[i] << " ";
return os;
}
template<typename T>
ostream& operator<<(ostream& os, const set<T>& v)
{
for (typename set<T>::iterator it = v.begin(); it != v.end(); it++)
os << *it << " ";
return os;
}
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
template <typename T>
class SegTreeLazyRangeSet {
vector<T> tree, lazy;
vector<T>* arr;
int n, root, n4, end;
void maintain(int cl, int cr, int p) {
int cm = cl + (cr - cl) / 2;
if (cl != cr && lazy[p]) {
lazy[p * 2] = lazy[p];
lazy[p * 2 + 1] = lazy[p];
tree[p * 2] = lazy[p] * (cm - cl + 1);
tree[p * 2 + 1] = lazy[p] * (cr - cm);
lazy[p] = 0;
}
}
T range_sum(int l, int r, int cl, int cr, int p) {
if (l <= cl && cr <= r) return tree[p];
int m = cl + (cr - cl) / 2;
T sum = 0;
maintain(cl, cr, p);
if (l <= m) sum += range_sum(l, r, cl, m, p * 2);
if (r > m) sum += range_sum(l, r, m + 1, cr, p * 2 + 1);
return sum;
}
void range_set(int l, int r, T val, int cl, int cr, int p) {
if (l <= cl && cr <= r) {
lazy[p] = val;
tree[p] = (cr - cl + 1) * val;
return;
}
int m = cl + (cr - cl) / 2;
maintain(cl, cr, p);
if (l <= m) range_set(l, r, val, cl, m, p * 2);
if (r > m) range_set(l, r, val, m + 1, cr, p * 2 + 1);
tree[p] = tree[p * 2] + tree[p * 2 + 1];
}
void build(int s, int t, int p) {
if (s == t) {
tree[p] = (*arr)[s];
return;
}
int m = s + (t - s) / 2;
build(s, m, p * 2);
build(m + 1, t, p * 2 + 1);
tree[p] = tree[p * 2] + tree[p * 2 + 1];
}
public:
explicit SegTreeLazyRangeSet<T>(vector<T> v) {
n = v.size();
n4 = n * 4;
tree = vector<T>(n4, 0);
lazy = vector<T>(n4, 0);
arr = &v;
end = n - 1;
root = 1;
build(0, end, 1);
arr = nullptr;
}
void show(int p, int depth = 0) {
if (p > n4 || tree[p] == 0) return;
show(p * 2, depth + 1);
for (int i = 0; i < depth; ++i) putchar('\t');
printf("%d:%d\n", tree[p], lazy[p]);
show(p * 2 + 1, depth + 1);
}
T range_sum(int l, int r) { return range_sum(l, r, 0, end, root); }
void range_set(int l, int r, int val) { range_set(l, r, val, 0, end, root); }
};
void solve()
{
int n,m;
cin >> n >> m;
SegTreeLazyRangeSet<int> tr(vector<int>(m,0));
map<int, int> mp;
for(int i=0;i<n;i++)
{
int x;
cin >> x;
mp[x]++;
}
vector<int> a(m);
for (int& x : a)
cin >> x;
int q;
cin >> q;
vector<pair<int,pair<int, int>>> qu(q);
for (int i = 0; i < q; i++)
qu[i].first = i;
for (auto& p : qu)
{
cin >> p.second.first >> p.second.second;
}
sort(qu.begin(), qu.end(), [&](auto& p1, auto& p2) {
if (p1.second.second == p2.second.second)
return p1.second.first < p2.second.first;
else
return p1.second.second < p2.second.second;
});
int rp = -1;
map<int, int> hm;
vector<int> ans(q,0);
for (int i = 0; i < q; i++)
{
int l = qu[i].second.first, r = qu[i].second.second;
l--; r--;
while (r > rp)
{
rp++;
int val = a[rp];
if (hm.find(val)!=hm.end())
{
tr.range_set(hm[val], hm[val], 0);
}
tr.range_set(rp, rp, mp[val]);
hm[val] = rp;
}
ans[qu[i].first] = tr.range_sum(l, r);
}
for (int x : ans)
cout << x << endl;
}
/*
边界、0特殊情况
可不可以二分答案或者其它
注释掉freopen
*/
int main()
{
int t = 1;
while (t--)
{
solve();
}
}