hdu 3333 树状数组

来源:互联网 发布:java应用软件开发 编辑:程序博客网 时间:2024/04/28 00:47

此题与3743相仿,但本题数据较大,需要用到离散化。

如何去掉重复元素呢?采用离线算法

首先将询问按右端点从小到大排序,离线处理时,记录每个元素所在位置,遇到重复元素时,从它之前出现的位置减去这个元素,这样就是的每个元素总是出现在最后。

#include<iostream>#include<cstdio>#include<algorithm>#include<string>#include<cstring>using namespace std;long long int a[301000];long long int c[310000];long long int flag[301000];__int64 ss[310000];long long int mm;int n;struct node{    long long int data;    long long int pos;}s[310000];long long int s1[310000];bool cmp(node x,node y){    return x.data<y.data;}struct node1{    int ll;    int rr;    int pos;}q[1100000];bool cmp1(node1 x,node1 y){    return x.rr<y.rr;}int lowbit(int x){    return x&(-x);}void add(int k,int detal){    while(k<=n)    {        c[k]+=detal;        k+=lowbit(k);    }}long long int sum(int k){    long long int t=0;    while(k>0)    {        t+=c[k];        k-=lowbit(k);    }    return t;}int main(){    int T;    int i,j;    int m;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        for(i=1;i<=n;i++)        {            scanf("%lld",&s[i].data);            s1[i]=s[i].data;            s[i].pos=i;        }        sort(s+1,s+n+1,cmp);        a[s[1].pos]=1;        mm=1;        for(i=2;i<=n;i++)        {            if(s[i].data==s[i-1].data)                a[s[i].pos]=a[s[i-1].pos];            else                a[s[i].pos]=a[s[i-1].pos]+1;            if(a[s[i].pos]>mm)                mm=a[s[i].pos];        }        //cout<<"mm:"<<mm<<endl;        memset(flag,0,sizeof(flag));        memset(c,0,sizeof(c));        scanf("%d",&m);        for(i=0;i<m;i++)        {            scanf("%d%d",&q[i].ll,&q[i].rr);            q[i].pos=i;        }        sort(q,q+m,cmp1);        int j=0;        for(i=1;i<=n;i++)        {            //cout<<i<<":"<<s1[i]<<endl;            if(flag[a[i]]==0)            {                add(i,s1[i]);                flag[a[i]]=i;            }            else            {                //cout<<i<<"  ha  "<<flag[a[i]]<<endl;                add(i,s1[i]);                add(flag[a[i]],-s1[i]);                flag[a[i]]=i;            }            while(q[j].rr==i)            {                ss[q[j].pos]=sum(q[j].rr)-sum(q[j].ll-1);                j++;            }            if(j>m)                break;        }        for(i=0;i<m;i++)        {            printf("%I64d\n",ss[i]);        }    }    return 0;}


 

原创粉丝点击