HDU 3333 Turing Tree 樹狀數組 離線查詢

來源:互聯網
上載者:User

標籤:style   blog   os   io   for   ar   問題   div   

題意: 給你一個數列,然後有n個查詢,問你給定區間中不同數位和是多少。

思路還是比較難想的,起碼對於蒟蒻我來說。

將區間按照先右端點,後左端點從小到大排序之後,對於每個查詢,我只要維護每個數字出現的最後一次就可以了(這個結論稍微想一下就可以證明是正確的)。

然後就是簡單的點更新,區間求和問題了~

#include <cstdio>#include <cstring>#include <iostream>#include <map>#include <set>#include <vector>#include <string>#include <queue>#include <deque>#include <bitset>#include <list>#include <cstdlib>#include <climits>#include <cmath>#include <ctime>#include <algorithm>#include <stack>#include <sstream>#include <numeric>#include <fstream>#include <functional>using namespace std;#define MP make_pair#define PB push_backtypedef long long LL;typedef unsigned long long ULL;typedef vector<int> VI;typedef pair<int,int> pii;const int INF = INT_MAX / 3;const double eps = 1e-8;const LL LINF = 1e17;const double DINF = 1e60;const int maxn = 3e4 + 10;struct Seg {    int l,r,id;    LL ans;    Seg(int l,int r,int id): l(l),r(r),id(id) {}}; int n,val[maxn],last[maxn],m;VI num;vector<Seg> query;LL C[maxn];bool ext[maxn];bool cmp(const Seg &a,const Seg &b) {    if(a.r == b.r) return a.l < b.l;    return a.r < b.r;}bool cmp1(const Seg &a,const Seg &b) {    return a.id < b.id;}inline int lowbit(int x) {    return x & (-x);}void addv(int pos,LL v) {    while(pos <= n) {        C[pos] += v; pos += lowbit(pos);    }}LL ask_(int pos) {    LL ret = 0;    while(pos > 0) {        ret += C[pos]; pos -= lowbit(pos);    }    return ret;}LL ask(int l,int r) {    return ask_(r) - ask_(l - 1);}int getID(int Val) {    return lower_bound(num.begin(),num.end(),Val) - num.begin() + 1;}void solve() {    memset(C,0,sizeof(C));    memset(last,-1,sizeof(last));    int npos = 1;    for(int i = 0;i < m;i++) {        Seg &now = query[i];        while(npos <= now.r) {            int nowval = getID(val[npos]);            if(last[nowval] != -1) addv(last[nowval],-val[npos]);            last[nowval] = npos;            addv(npos,val[npos]);            npos++;        }        now.ans = ask(now.l,now.r);    }}int main() {    int T; scanf("%d",&T);    while(T--) {        query.clear();        num.clear();        int tmp; scanf("%d",&n);        for(int i = 1;i <= n;i++) {            scanf("%d",&val[i]); num.PB(val[i]);        }        sort(num.begin(),num.end());        num.erase(unique(num.begin(),num.end()),num.end());        scanf("%d",&m);        for(int i = 0;i < m;i++) {            int l,r; scanf("%d%d",&l,&r);            query.PB(Seg(l,r,i));        }        sort(query.begin(),query.end(),cmp);        solve();        sort(query.begin(),query.end(),cmp1);        for(int i = 0;i < m;i++) cout << query[i].ans << endl;    }    return 0;}

  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.