hdu 4325

来源:互联网 发布:mysql 拼接字符串函数 编辑:程序博客网 时间:2024/06/05 17:10

题目

线段树成段更新,我用了离散化

#include<stdio.h>#include<string.h>#include<map>#include<algorithm>using namespace std;map<int,int>m;map<int,int>::iterator it;int x[100000+1],y[100000+1],q[100000+1];int li[100000*3+5],k;int t,n,M;struct node{    int l,r,num,lazy;}root[100000*3*4+10];inline void build(int t,int x,int y){    root[t].num=root[t].lazy=0;    root[t].l=x,root[t].r=y;    if(x==y) return;    int m=(x+y)>>1;    build(t*2,x,m);    build(t*2+1,m+1,y);}inline void Modefiy(int t,int x,int y,int val){    int l=root[t].l,r=root[t].r;    int m=(l+r)>>1;    if(l==x&&r==y)    {        root[t].num+=(y-x+1)*val;        root[t].lazy+=val;        return;    }    if(root[t].lazy!=0)    {        Modefiy(t*2,l,m,root[t].lazy);        Modefiy(t*2+1,m+1,r,root[t].lazy);        root[t].lazy=0;    }    if(x<=m) Modefiy(t*2,x,min(m,y),val);    if(y>m) Modefiy(t*2+1,max(m+1,x),y,val);    root[t].num=root[t*2].num+root[t*2+1].num;}inline int query(int t,int x){    int l=root[t].l;    int r=root[t].r;    int mid=(l+r)>>1;    if(l==x&&r==x)    {        return root[t].num;    }    if(root[t].lazy!=0)    {        Modefiy(t*2,l,mid,root[t].lazy);        Modefiy(t*2+1,mid+1,r,root[t].lazy);        root[t].lazy=0;    }    if(x<=mid) return query(t*2,x);    else  return query(t*2+1,x);}int main(){    int ca=1;    scanf("%d",&t);    while(t--)    {        k=1;        m.clear();        scanf("%d%d",&n,&M);        for(int i=1;i<=n;i++)        {            scanf("%d%d",&x[i],&y[i]);            if(m[x[i]]==0) m[x[i]]=1;            if(m[y[i]]==0) m[y[i]]=1;        }        for(int i=1;i<=M;i++)        {            scanf("%d",&q[i]);            if(m[q[i]]==0) m[q[i]]=1;        }        for(it=m.begin();it!=m.end();it++)        {            m[it->first]=k;            li[k++]=it->first;        }        printf("Case #%d:\n",ca++);        build(1,1,k);        for(int i=1;i<=n;i++)        {            Modefiy(1,m[x[i]],m[y[i]],1);        }        for(int i=1;i<=M;i++)        {            int x=m[q[i]];            printf("%d\n",query(1,x));        }    }}


 

 

树状数组:<挑战程序竞赛>上讲树状数组时,讲了用树状数组,更新区间,在P181.不明觉厉

#include<stdio.h>#include<string.h>#include<map>#include<algorithm>using namespace std;map<int,int>m;map<int,int>::iterator it;int x[100000+1],y[100000+1],q[100000+1];int li[100000*3+5],k;int t,n,M;int c1[100000*3+10],c2[100000*3+10];int lowbit(int x){    return x&(-x);}void Modefiy(int *c,int x,int val){    while(x<k)    {        c[x]+=val;x+=lowbit(x);    }}int query(int *c,int x){    int a=0;    while(x>0)    {        a+=c[x],x-=lowbit(x);    }    return a;}int main(){    int ca=1;    scanf("%d",&t);    while(t--)    {        k=1;        m.clear();        scanf("%d%d",&n,&M);        for(int i=1;i<=n;i++)        {            scanf("%d%d",&x[i],&y[i]);            if(m[x[i]]==0) m[x[i]]=1;            if(m[y[i]]==0) m[y[i]]=1;        }        for(int i=1;i<=M;i++)        {            scanf("%d",&q[i]);            if(m[q[i]]==0) m[q[i]]=1;        }        for(it=m.begin();it!=m.end();it++)        {            m[it->first]=k;            li[k++]=it->first;        }        printf("Case #%d:\n",ca++);        memset(c1,0,sizeof(c1));        memset(c2,0,sizeof(c2));        for(int i=1;i<=n;i++)        {            int a=m[x[i]],b=m[y[i]];            Modefiy(c1,a,-1*(a-1));            Modefiy(c2,a,1);            Modefiy(c1,b+1,1*b);            Modefiy(c2,b+1,-1);        }        for(int i=1;i<=M;i++)        {            int a=m[q[i]];            int ans1=query(c1,a)+query(c2,a)*a;            ans1-=query(c1,a-1)+query(c2,a-1)*(a-1);            printf("%d\n",ans1);        }    }    return 0;}


 

原创粉丝点击