hdu 3333 Turing Tree 线段树/树状数组

题意:求给定去接内不重复数字的和

做法: 图灵树还是没有学到....

只要先记录每个询问,然后按照右边界排序,还需要记录每个位置之前距离它最近那个与他相等的元素的位置。再树状数组做一下。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define lowbit(x) ((x)&-(x))
typedef __int64 LL;
const int LMT = 30003;
using namespace std;
struct __line
{
    int l, r, pos;
    bool operator < (const __line &y)const
    {
        return r < y.r;
    }
}line[100003];
struct __copy
{
    int num, pos;
    bool operator < (const __copy &y)const
    {
        if(num != y.num) return num < y.num;
        return pos < y.pos;
    }
}a_copy[LMT];
int a[LMT], n, vis[LMT];
LL sum[LMT], ans[100002];
void update(int op, int x)
{
    while(x <= n)
    {
        sum[x] += op;
        x += lowbit(x);
    }
}
LL query(int x)
{
    LL res = 0;
    while(x > 0)
    {
        res += sum[x];
        x -= lowbit(x);
    }
    return res;
}
int main(void)
{
    int q, i, j, T;
    scanf("%d", &T);
    while(T--)
    {
        memset(vis, -1, sizeof(vis));
        memset(sum, 0, sizeof(sum));
        scanf("%d", &n);
        for(i = 1; i <= n; ++i)
        {
            scanf("%d", &a[i]);
            a_copy[i].num = a[i];
            a_copy[i].pos = i;
        }
        scanf("%d", &q);
        for(i = 0; i < q; ++i)
        {
            scanf("%d%d", &line[i].l, &line[i].r);
            line[i].pos = i;
        }
        sort(line, line + q);
        sort(&a_copy[1], &a_copy[1] + n);
        for( i = 2; i <= n; ++i)
            if (a_copy[i].num == a_copy[i - 1].num)
                vis[a_copy[i].pos] = a_copy[i - 1].pos;
        for(i = 1, j = 0; i <= n && j < q; ++i)
        {
            update(a[i], i);
            if (vis[i] != -1) update(-a[i], vis[i]);
            while(j < q && line[j].r == i)
            {
                ans[line[j].pos] = query(line[j].r) - query(line[j].l - 1);
                ++j;
            }
        }
        for(i = 0; i < q; ++i)printf("%I64d\n", ans[i]);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值