HDU 3333 & 3874 (线段树+离线询问)

两个题目都是求区间之内,不重复的数字之和,3333需要离散化处理.................

调试了一下午........说多了都是泪...........

 

#include <iostream>

#include <algorithm>

#include <cmath>

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <string>

#include <map>

#include <queue>

#include <climits>//形如INT_MAX一类的

#define MAX 51111

#define INF 0x7FFFFFFF

#define L(x) x<<1

#define R(x) x<<1|1

//#pragma comment(linker, "/STACK:36777216") ///传说中的外挂

using namespace std;



inline void RD(int &ret) {

    char c;

    do {

        c = getchar();

    } while(c < '0' || c > '9') ;

    ret = c - '0';

    while((c=getchar()) >= '0' && c <= '9')

        ret = ret * 10 + ( c - '0' );

}



inline void OT(int a) {

    if(a >= 10)OT(a / 10) ;

    putchar(a % 10 + '0') ;

}



struct node {

    int l,r,mid,cover;

    __int64 sum;

} tree[MAX*4];



int n,m;

int a[MAX],va[MAX],pos[MAX],tmp[MAX];

__int64 ans[111111 * 2];



struct Node {

    int l,r;

    int id;

} qes[111111 * 2];



void init() {

    memset(va,0,sizeof(va));

}

int search(int l,int r,int x) {

    int mid;

    while(l <= r) {

        mid = (l+r) >> 1;

        if(pos[mid] == x) return mid;

        else if(pos[mid] > x) r = mid -1;

        else l = mid + 1;

    }

}



void up(int num) {

    tree[num].sum = tree[L(num)].sum + tree[R(num)].sum;

}



void build(int l,int r,int num) {

    tree[num].l = l;

    tree[num].r = r;

    tree[num].mid = (l+r) >> 1;

    tree[num].cover = 0;

    tree[num].sum = 0;

    if(l == r) {

        tree[num].sum = va[l];

        return ;

    }

    build(l,tree[num].mid,L(num));

    build(tree[num].mid + 1,r,R(num));

    up(num);

}



void update(int l,int x,int color) {

    if(tree[x].l == tree[x].r) {

        tree[x].sum += color;

        return ;

    }

    if(l > tree[x].mid) update(l,R(x),color);

    else update(l,L(x),color);

    up(x);

}



__int64 query(int l,int r,int num) {

    if(l == tree[num].l && tree[num].r == r) {

        return tree[num].sum;

    }

    if(r <= tree[num].mid) {

        return query(l,r,L(num));

    } else if(l > tree[num].mid) {

        return query(l,r,R(num));

    } else {

        return query(l,tree[num].mid,L(num)) + query(tree[num].mid+1,r,R(num));

    }

}





bool cmp(const Node &a,const Node &b) {

    if(a.r == b.r) return a.l < b.l;

    return a.r < b.r;

}



bool cmp2(const int &a, const int &b) {

    return a < b;

}

int main() {

    int T;

    cin >> T;

    while(T --) {

        init();

        RD(n);

        int t = 1;

        for(int i=1; i<=n; i++) {

            RD(a[i]);

            tmp[i] = a[i];

        }

        sort(tmp+1,tmp+1+n,cmp2);

        pos[1] = tmp[1];

        for(int i=2; i<=n; i++) {

            if(tmp[i] != tmp[i-1]) {

                pos[++t] = tmp[i];

            }

        }

        build(1,n,1);

        RD(m);

        for(int i=1; i<=m; i++) {

            RD(qes[i].l);

            RD(qes[i].r);

            qes[i].id = i;

        }

        sort(qes+1,qes+1+m,cmp);

        int order = 1;

        for(int i=1; i<=m; i++) {

            while(qes[i].r >= order) {

                int id = search(1,t,a[order]);

                int ps = va[id];

                if( ps != 0) update(ps,1,-a[order]);

                va[id] = order;

                update(va[id],1,a[order]);

                order ++;

            }

            ans[qes[i].id] = query(qes[i].l,qes[i].r,1);

        }

        for(int i=1; i<=m; i++) {

            printf("%I64d\n",ans[i]);

        }

    }

    return 0;

}


 

 

你可能感兴趣的:(HDU)