HDU 3333 线段树强制离线处理

来源:互联网 发布:软件著作权申请表范本 编辑:程序博客网 时间:2024/05/21 05:18

http://acm.hdu.edu.cn/showproblem.php?pid=3333

作为一个萌新第一次遇到这种题是很绝望的,大佬的姿势真多!!!


题意:n个数字,m次查询,求每次查询区间数的和(重复的只算一遍)


思路:如果是在线处理要T,只能强制离线(来自大佬的一句话)

           1.将m次询问一次性读入,按右端点从小到大排序,如果右端点一样,那左端点从小到大排序

           2.用map 记录每个数上一次出现的位置(本来应该离散化的,stl大法吼啊),

                 2.1如果当前数字没出现过直接线段树单点更新,加上即可

                 2.2否则,通过map找到上一次出现的位置 先将其位置改为0,然后再修改当前点的值

           3.for循环一次性处理完所有答案


这个强制离线吊啊!!orz

#include <iostream>#include<algorithm>#include<stdio.h>#include<string.h>#include<map>#define lson  node<<1, l,mid#define rson  node<<1|1, mid+1,rusing namespace std;const int maxn=30005;const int maxm=100005;typedef long long ll;ll a[maxn];ll ans[maxm];ll tree[maxn<<2];void pushup(int node){   tree[node]=tree[node<<1]+tree[node<<1|1];}void updata(int node,int l,int r,int pos,int x){    if(l==r)    {        tree[node]=x;        return;    }    int mid=(l+r)>>1;    if(mid>=pos)        updata(lson,pos,x);    else updata(rson,pos,x);        pushup(node);}ll qurry(int node ,int l,int r, int begin ,int end){    if(l>=begin&&r<=end)    {        return tree[node];    }    ll sum=0;    int mid=(l+r)>>1;    if(mid>=begin)    {        sum+=qurry(lson,begin,end);    }    if(mid<end)    {        sum+=qurry(rson,begin,end);    }    return sum;}struct node{    int id,l,r;}q[maxm];bool cmp(const node a,const node b){    if(a.r!=b.r) return a.r<b.r;    return a.l<b.l;}int main(){    int T;    scanf("%d",&T);    while(T--)    {        memset(tree,0,sizeof(tree));        int n,m;        scanf("%d",&n);        for(int i=1;i<=n;i++)        {            scanf("%I64d\n",&a[i]);        }        scanf("%d",&m);        for(int i=1;i<=m;i++)        {            q[i].id=i;            scanf("%d%d",&q[i].l,&q[i].r);        }        sort(q+1,q+1+m,cmp);        map<ll,int> vis;        int now=1;        for(int i=1;i<=m;i++)        {           while(q[i].r>=now)            {                if(vis[a[now]]!=0)                {                     updata(1,1,n,vis[a[now]],0);                }                updata(1,1,n,now,a[now]);                vis[a[now]]=now;                now++;            }           ans[q[i].id]=qurry(1,1,n,q[i].l,q[i].r);        }        for(int i=1;i<=m;i++)        {            printf("%I64d\n",ans[i]);        }    }    return 0;}




0 0
原创粉丝点击