Turing Tree HDU - 3333 (树状数组,离线求区间元素种类数)
After inventing Turing Tree, 3xian always felt boring when solving problems about intervals, because Turing Tree could easily have the solution. As well, wily 3xian made lots of new problems about intervals. So, today, this sick thing happens again...
Now given a sequence of N numbers A1, A2, ..., AN and a number of Queries(i, j) (1≤i≤j≤N). For each Query(i, j), you are to caculate the sum of distinct values in the subsequence Ai, Ai+1, ..., Aj.
给定一个长度为n的序列,给定m个查询,每次查询区间[L,R]范围内不同元素的和。
Input
The first line is an integer T (1 ≤ T ≤ 10), indecating the number of testcases below.
For each case, the input format will be like this:
- Line 1: N (1 ≤ N ≤ 30,000).
- Line 2: N integers A1, A2, ..., AN (0 ≤ Ai ≤ 1,000,000,000).
- Line 3: Q (1 ≤ Q ≤ 100,000), the number of Queries.
- Next Q lines: each line contains 2 integers i, j representing a Query (1 ≤ i ≤ j ≤ N). 第一个整数T,表示数据组数。
对于每组数据,第一行一个整数n,表示序列中元素个数。
第二行n个元素。
第三行一个整数q,表示询问的组数。
接下来q行,每行两个整数L和R
Output
For each Query, print the sum of distinct values of the specified subsequence in one line.
对于每个询问,输出结果。
Sample Input
2
3
1 1 4
2
1 2
2 3
5
1 1 2 1 3
3
1 5
2 4
3 5
Sample Output
1
5
6
3
6
题意:
英文下面有中文翻译
思路:
先把区间信息读进来,然后以右端点排序,然后离线处理每一个区间信息,同时用一个map来维护一个数值x最后一次出现的位置。
细节见代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <bits/stdc++.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int* p);
const int maxn = 30010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int q;
int n;
ll tree[maxn];
int lowbit(int x)
{
return -x&x;
}
void add(int x,ll val)
{
while(x<maxn)
{
tree[x]+=val;
x+=lowbit(x);
}
}
ll ask(int x)
{
ll res=0;
while(x)
{
res+=tree[x];
x-=lowbit(x);
}
return res;
}
ll a[maxn];
map<ll,int> vis;
struct node
{
int l,r;
int id;
}b[100010];
bool cmp(node aa,node bb)
{
return aa.r<bb.r;
}
bool cmp2(node aa,node bb)
{
return aa.id<bb.id;
}
ll ans[100010];
int main()
{
//freopen("D:\\code\\text\\input.txt","r",stdin);
//freopen("D:\\code\\text\\output.txt","w",stdout);
gbtb;
int t;
cin>>t;
while(t--)
{
MS0(tree);
vis.clear();
cin>>n;
repd(i,1,n)
{
cin>>a[i];
}
int q;
cin>>q;
repd(i,1,q)
{
cin>>b[i].l;
cin>>b[i].r;
b[i].id=i;
}
sort(b+1,b+1+q,cmp);
int p=1;
repd(i,1,q)
{
while(p<=b[i].r)
{
if(vis[a[p]])
{
add(vis[a[p]],-a[p]);
add(p,a[p]);
vis[a[p]]=p;
}else
{
vis[a[p]]=p;
add(p,a[p]);
}
p++;
}
ans[b[i].id]=ask(b[i].r)-ask(b[i].l-1);
}
sort(b+1,b+1+q,cmp2);
repd(i,1,q)
{
cout<<ans[b[i].id]<<endl;
}
}
return 0;
}
inline void getInt(int* p) {
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '0');
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 - ch + '0';
}
}
else {
*p = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 + ch - '0';
}
}
}
本博客为本人原创,如需转载,请必须声明博客的源地址。
本人博客地址为:www.cnblogs.com/qieqiemin/
希望所写的文章对您有帮助。