D-Query
segment tree + offline method
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <map>
#define sf(i) scanf("%d", &i)
#define pf(i) printf("%d\n", i)
using namespace std;
const int N = 30001;
const int Q = 200001;
struct node
{
int l, r;
int pos,
int val;
};
int n, q;
node arr[N + Q];
int result[Q];
int seg[4 * N];
map<int, int> last_pos;
node makenode(int l, int r, int pos, int val)
{
node temp;
temp.l = l;
temp.r = r;
temp.pos = pos;
temp.val = val;
return temp;
}
void update(int l, int r, int index, int pos, int val)
{
if(l == r)
{
seg[index] = val;
}
else
{
int mid = (r + l) / 2;
if(pos <= mid)
{
update(l, mid, 2 * index, pos, val);
}
else
{
update(mid + 1, r, 2 * index + 1, pos, val);
}
seg[index] = seg[index << 1] + seg[(index << 1) + 1];
}
}
int query(int l, int r, int index, int qs, int qe)
{
if(qs > r || qe < l)
return 0;
if(qs <= l && qe >= r)
return seg[index];
int mid = (l + r) / 2;
int a = query(l, mid, 2 * index, qs, qe);
int b = query(mid + 1, r, 2 * index + 1, qs, qe);
return a + b;
}
bool comp(node a, node b)
{
if(a.pos == b.pos)
{
return a.r < b.r;
}
return (a.pos < b.pos);
}
int main()
{
int l, r;
sf(n);
int index = 0;
int temp;
for(int i = 1; i <= n; i++)
{
sf(temp);
arr[index++] = makenode(-1, -1, i, temp);
}
sf(q);
for(int i = 1; i <= q; i++)
{
sf(l), sf(r);
arr[index++] = makenode(l, r, r, i); // stores position as value in case of query
}
sort(arr, arr + index, comp);
for(int i = 0; i < index; i++)
{
if(arr[i].l == -1 && arr[i].r == -1)
{
if(last_pos[arr[i].val] == 0)
{
update(1, n, 1, arr[i].pos, 1); //if value does not exist update the pos with 1
}
else
{
update(1, n, 1, last_pos[arr[i].val], 0); // if value already exist then update the old pos with 0
update(1, n, 1, arr[i].pos, 1); // update the new pos with 1
}
last_pos[arr[i].val] = arr[i].pos; // update the last position array
}
else
{
int ans = query(1, n, 1, arr[i].l, arr[i].r);
result[arr[i].val] = ans;
}
}
for(int i = 1; i <= q; i++)
{
pf(result[i]);
}
return 0;
}
Comments
Post a Comment