標籤:second 圖靈 out nbsp mes 出現 upd 資料 div
Turing Tree
http://acm.hdu.edu.cn/showproblem.php?pid=3333
分析:
這道題目叫 圖靈樹。
離線+樹狀數組。
維護到每個右端點的答案,直接查詢左端點,樹狀數組維護。一個數字不能出現兩次,會發現如果出現了多個數,最右邊的數可以代替左邊的所有數,所以只加入最右邊一個數即可。
代碼:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<cctype> 7 #include<set> 8 #include<vector> 9 #include<queue>10 #include<map>11 #define pa pair<int,int>12 #define mp make_pair13 #define fi(s) freopen(s,"r",stdin);14 #define fo(s) freopen(s,"w",stdout);15 using namespace std;16 typedef long long LL;17 18 inline int read() {19 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch==‘-‘)f=-1;20 for(;isdigit(ch);ch=getchar())x=x*10+ch-‘0‘;return x*f;21 }22 23 const int N = 30005;24 25 struct Bit{26 int n; LL sum[N];27 void Clear() { memset(sum, 0, sizeof(sum)); }28 void update(int p,int v) {29 for (; p<=n; p+=(p&(-p))) sum[p] += v;30 }31 LL query(int p) {32 LL ans = 0;33 for (; p; p-=(p&(-p))) ans += sum[p];34 return ans;35 }36 }bit;37 int last[N], disc[N], a[N];38 LL ans[100005]; // 資料範圍! 39 vector< pa > vec[N];40 41 void solve() { 42 int n = read(), cnt = 1;43 for (int i=1; i<=n; ++i) 44 a[i] = read(), disc[i] = a[i];45 sort(disc + 1, disc + n + 1);46 for (int i=2; i<=n; ++i) if (disc[i] != disc[cnt]) disc[++cnt] = disc[i];47 for (int i=1; i<=n; ++i) 48 a[i] = lower_bound(disc + 1, disc + cnt + 1, a[i]) - disc;49 int Q = read();50 for (int i=1; i<=Q; ++i) {51 int l = read(), r = read();52 vec[r].push_back(mp(l, i));53 }54 bit.n = n;55 for (int i=1; i<=n; ++i) {56 if (last[a[i]]) bit.update(last[a[i]], -disc[a[last[a[i]]]]);57 bit.update(i, disc[a[i]]);58 last[a[i]] = i;59 for (int sz=vec[i].size(),j=0; j<sz; ++j) 60 ans[vec[i][j].second] = bit.query(i) - bit.query(vec[i][j].first - 1);61 }62 for (int i=1; i<=Q; ++i) printf("%lld\n",ans[i]);63 bit.Clear();64 memset(last, 0, sizeof(last));65 for (int i=1; i<=n; ++i) vec[i].clear();66 }67 68 int main() {69 int T = read();70 while (T--) 71 solve();72 return 0;73 }
HDU 3333 Turing Tree