HDU 3333 Turing Tree(線段樹+離線操作)
Turing Tree
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5385 Accepted Submission(s): 1909
Problem Description
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.
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.
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).
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).
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
Author
3xian@GDUT
Source
題意:
求區間內和,重複的值不算。
POINT:
看了題解,用離線操作,沒想到還有這種操作。
解釋一下就是:
先按照所需求區間的右端點排序。線段樹區間儲存的就是合。
一個一個插入點,如果遇到之前插入過的,把舊的更新成0,新的再插入。這樣就能實現,i這個狀態下 (1-i)區間裡的數字都只出現了一次,然後當有右端點==i時,求一下sum(l-r),儲存答案就行。
然後按照原順序輸出。小細節程式碼裡有註釋。
並不需要離散化。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
#define rt x<<1|1
#define lt x<<1
const int N = 30000*8;
#define LL long long
LL a[N],sum[N];
map<LL,int> mp;
struct node
{
int l,r,i;
}q[N];
bool cmd(node c,node b)
{
return c.r<b.r;
}
void init()
{
mp.clear();
memset(q,0,sizeof q);
memset(sum,0,sizeof sum);
memset(a,0,sizeof a);
}
void change(int x,int l,int r,int i,LL k)
{
if(l==r&&r==i) sum[x]=k;
else
{
int mid=(l+r)>>1;
if(i<=mid) change(lt,l,mid,i,k);
if(mid<i) change(rt,mid+1,r,i,k);
sum[x]=sum[lt]+sum[rt];
}
}
LL query(int x,int l,int r,int ll,int rr)
{
LL ans=0;
if(ll<=l&&rr>=r) ans+=sum[x];
else
{
int mid=(l+r)>>1;
if(ll<=mid) ans+=query(lt,l,mid,ll,rr);
if(mid<rr) ans+=query(rt,mid+1,r,ll,rr);
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
init();
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
int Q;
scanf("%d",&Q);
for(int i=1;i<=Q;i++)
{
scanf("%d %d",&q[i].l,&q[i].r);
q[i].i=i;
}
sort(q+1,q+1+Q,cmd);
LL ans[N];
for(int i=1,j=1;i<=n;i++)
{
if(mp[a[i]])
{
change(1,1,n,mp[a[i]],0);
change(1,1,n,i,a[i]);
mp[a[i]]=i;
}
else
{
mp[a[i]]=i;
change(1,1,n,i,a[i]);
}
while(j<=Q&&q[j].r==i)//有多個區間的r相等的情況,所以用while
{
ans[q[j].i]=query(1,1,n,q[j].l,q[j].r);
j++;
}
}
for(int i=1;i<=Q;i++)
{
printf("%lld\n",ans[i]);
}
}
return 0;
}
相關文章
- hdu4288 離線處理線段樹
- hdu 4836 The Query on the Tree(線段樹or樹狀陣列)陣列
- Transformation HDU - 4578線段樹綜合操作ORM
- 線段樹 transformation——hdu 4578ORM
- 淺談線段樹(Segment Tree)
- 線段樹入門(Segment Tree)
- hdu 1754 I Hate It (線段樹)
- hdu 1754 【線段樹/RMQ】I Hate ItMQ
- hdu 3973 字串hash+線段樹字串
- HDU 1754 I Hate It 線段樹入門
- HDU 5200 Tree (離線並查集)並查集
- HDU 1556 Color the ball(線段樹|樹狀陣列)陣列
- hdu 4368 樹狀陣列 離線維護陣列
- HDU 1754 I Hate It (線段樹 區間最值)
- hdu 1394 Minimum Inversion Number 【線段樹查詢】
- HDU 1556 Color the ball 線段樹入門題
- HDU 1698 Just a Hook (線段樹區間更新)Hook
- 線~段~樹
- 線段樹
- hdu 2665 可持久化線段樹求區間第K大值(函式式線段樹||主席樹)持久化函式
- 【學習筆記】Segment Tree Beats/吉司機線段樹筆記
- HDU 3074 Multiply game(線段樹 單點更新)GAM
- (hdu 1754) I Hate It(線段樹基礎,單點更新)
- 線段樹(3)——區間操作疊加
- 線段樹 hate it
- 【模版】線段樹
- 01 線段樹
- 線段樹--RMQMQ
- 李超線段樹
- 線段樹模板
- ut.cpp 最大線段並減線段交 [線段樹]
- 【dp+離散化+線段樹優化】Paint優化AI
- TZOJ 8472 : Tree (重鏈剖分+線段樹) POJ 3237
- 線段樹筆記筆記
- 線段樹入門
- 權值線段樹
- 線段樹進階
- POJ 3468 A Simple Problem with Integers(線段樹區間操作)