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;
}
相關文章
- HDU 1542 Atlantis (線段樹+離散化+掃描線)
- Transformation HDU - 4578線段樹綜合操作ORM
- Segment Tree(線段樹)
- 線段樹 transformation——hdu 4578ORM
- HDU 1255 覆蓋的面積(線段樹+掃描線+離散化)
- 線段樹入門(Segment Tree)
- hdu 1698 線段樹 一段更新染色
- HDU 1394 Minimum Inversion Number (暴力+線段樹)
- HDU 2795 Billboard(線段樹 區間最大)
- HDU 1556 Color the ball(線段樹|樹狀陣列)陣列
- HDU 1166 敵兵佈陣 (線段樹 插點問線)
- HDU 3074 Multiply game(線段樹 單點更新)GAM
- HDU 1754 I Hate It (線段樹 區間最值)
- 線~段~樹
- 線段樹
- TZOJ 8472 : Tree (重鏈剖分+線段樹) POJ 3237
- 線段樹(3)——區間操作疊加
- HDU 4027 Can you answer these queries? (線段樹 區間開方)
- 【學習筆記】Segment Tree Beats/吉司機線段樹筆記
- [ABC337G] Tree Inversion(換根 dp + 值域線段樹)
- 線段樹模板
- 線段樹--RMQMQ
- 01 線段樹
- 線段樹 hate it
- 【模版】線段樹
- ut.cpp 最大線段並減線段交 [線段樹]
- ECNU OJ 3353 塗黑板(線段樹離散化)
- HDU 5862 Counting Intersections(樹狀陣列+掃描線+離散化)陣列
- HDU 3397 Sequence operation(線段樹區間染色加區間合併)
- bzoj1858: [Scoi2010]序列操作(線段樹)
- HDU 6035 Colorful Tree(樹形DP)
- 權值線段樹
- 線段樹筆記筆記
- 線段樹入門
- 李超線段樹
- 線段樹進階
- HDU1754 I Hate It 【線段樹基礎:點修改+區間查詢】
- 洛谷題單指南-線段樹-P3373 【模板】線段樹 2