HDOJ 4417 - Super Mario 线段树or树状数组离线处理..

来源:互联网 发布:cydia软件源更新 编辑:程序博客网 时间:2024/05/11 11:36

      题意:

                同上

      题解:

                抓着这题作死的搞~~是因为今天练习赛的一道题.SPOJ KQUERY.直到我用最后一种树状数组通过了HDOJ这题后..交SPOJ的才没超时..看排名...时间能排到11名了..有些叼...看下时间效率..自下而上: 划分树、线段树、树状数组、优化后的树状数组...


                划分树的效率最低...看来划分树的应用范围还是是很有局限性...只在求kth number的时候给力..逆过来求就已经力不从心了...

                线段树及树状数组处理本题..需要把询问都存下来...按照询问数从小到大按排个序..并且把每个数以及其序号存下来..按数字从小到大排个序...首先这一列数都是空的(全0)..然后边放数边统计结果...


Program:  线段树171MS

#include<iostream>#include<stdio.h>#include<string.h>#include<cmath>#include<queue>#include<stack>#include<set>#include<map>#include<algorithm>#define ll long long#define eps 1e-5#define oo 1000000007#define pi acos(-1.0)#define MAXN 100005using namespace std;struct node{       int x,w;  }p[MAXN];struct question{       int l,r,x,id; }q[200005];int sum[MAXN<<2],ans[200005];void update(int p,int x,int l,int r,int now){       if (l==r) { sum[now]=x; return; }       int mid=l+r>>1;       if (p<=mid) update(p,x,l,mid,now<<1);       if (p>mid)  update(p,x,mid+1,r,now<<1|1);       sum[now]=sum[now<<1]+sum[now<<1|1];       return; }int query(int L,int R,int l,int r,int now){       if (L<=l && R>=r) return sum[now];       int mid=l+r>>1,ans=0;       if (L<=mid) ans+=query(L,R,l,mid,now<<1);       if (R>mid)  ans+=query(L,R,mid+1,r,now<<1|1);              return ans;}bool cmp1(node a,node b) { return a.x<b.x; }bool cmp2(question a,question b) { return a.x<b.x; } int main(){                   int n,m,i,x,t,h,T,cases;         scanf("%d",&T);       for (cases=1;cases<=T;cases++)       {               printf("Case %d:\n",cases);               scanf("%d%d",&n,&m);               for (i=1;i<=n;i++) scanf("%d",&p[i].x),p[i].w=i;               sort(p+1,p+1+n,cmp1);               p[n+1].x=oo;                for (i=1;i<=m;i++)                {                     scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].x);                     q[i].l++,q[i].r++;                     q[i].id=i;               }               sort(q+1,q+1+m,cmp2);               memset(sum,0,sizeof(sum));               h=x=1;               while (x<=n && h<=m)               {                     t=p[x].x;                     while (p[x].x==t) update(p[x].w,1,1,n,1),x++;                     while (h<=m && q[h].x<t) ans[q[h].id]=0,h++;                     while (h<=m && q[h].x<p[x].x)                      ans[q[h].id]=query(q[h].l,q[h].r,1,n,1),h++;               }               for (i=1;i<=m;i++) printf("%d\n",ans[i]);       }       return 0;}


Program: 树状数组 125MS

#include<iostream>#include<stdio.h>#include<string.h>#include<cmath>#include<queue>#include<stack>#include<set>#include<map>#include<algorithm>#define ll long long#define eps 1e-5#define oo 1000000007#define pi acos(-1.0)#define MAXN 100005using namespace std;struct node{       int x,w;  }p[MAXN];struct question{       int l,r,x,id; }q[200005];int sum[MAXN],ans[200005],n; void insert(int x,int k){       while (k<=n)       {             sum[k]+=x;             k+=k&(-k);       }       return;}int query(int k){       int ans=0;       while (k)       {               ans+=sum[k];               k-=k&(-k);       }       return ans;}bool cmp1(node a,node b) { return a.x<b.x; }bool cmp2(question a,question b) { return a.x<b.x; } int main(){                   int m,i,x,t,h,T,cases;        scanf("%d",&T);       for (cases=1;cases<=T;cases++)       {               printf("Case %d:\n",cases);               scanf("%d%d",&n,&m);               for (i=1;i<=n;i++) scanf("%d",&p[i].x),p[i].w=i;               sort(p+1,p+1+n,cmp1);               p[n+1].x=oo;                for (i=1;i<=m;i++)                {                     scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].x);                     q[i].l++,q[i].r++;                     q[i].id=i;               }               sort(q+1,q+1+m,cmp2);               memset(sum,0,sizeof(sum));               h=x=1;               while (x<=n && h<=m)               {                     t=p[x].x;                     while (p[x].x==t) insert(1,p[x].w),x++;                     while (h<=m && q[h].x<t) ans[q[h].id]=0,h++;                     while (h<=m && q[h].x<p[x].x)                          ans[q[h].id]=query(q[h].r)-query(q[h].l-1),h++;               }               for (i=1;i<=m;i++) printf("%d\n",ans[i]);       }       return 0;}



Program: 树状数组 78MS

#include<iostream>#include<stdio.h>#include<string.h>#include<cmath>#include<queue>#include<stack>#include<set>#include<map>#include<algorithm>#define ll long long#define eps 1e-5#define oo 1000000007#define pi acos(-1.0)#define MAXN 100005#define MAXM 200005using namespace std;struct node{       int x,w;  }p[MAXN]; int sum[MAXN],ans[200005],n,ql[MAXM],qr[MAXM],qx[MAXM],qid[MAXM]; void insert(int x,int k){       while (k<=n)       {             sum[k]+=x;             k+=k&(-k);       }       return;}int query(int k){       int ans=0;       while (k)       {               ans+=sum[k];               k-=k&(-k);       }       return ans;}int input(){       char c;       do       {             c=getchar();       }while (c<'0' || c>'9');       int d=0;       while (c>='0' && c<='9')       {               d=d*10+c-'0';               c=getchar();       }       return d;}bool cmp1(node a,node b) { return a.x<b.x; }bool cmp2(int a,int b) { return qx[a]<qx[b]; } int main(){                   int m,i,x,t,h,T,cases;         scanf("%d",&T);       for (cases=1;cases<=T;cases++)       {              printf("Case %d:\n",cases);              scanf("%d%d",&n,&m);              for (i=1;i<=n;i++) p[i].x=input(),p[i].w=i;              sort(p+1,p+1+n,cmp1);              p[n+1].x=oo;                for (i=1;i<=m;i++)               {                   ql[i]=input()+1,qr[i]=input()+1,qx[i]=input();                   qid[i]=i;               }              sort(qid+1,qid+1+m,cmp2);              memset(sum,0,sizeof(sum));              h=x=1;                while (x<=n && h<=m)              {                   t=p[x].x;                   while (p[x].x==t) insert(1,p[x].w),x++;                   while (h<=m && qx[qid[h]]<t) ans[qid[h]]=0,h++;                   while (h<=m && qx[qid[h]]<p[x].x)                    ans[qid[h]]=query(qr[qid[h]])-query(ql[qid[h]]-1),h++;              }              for (i=1;i<=m;i++) printf("%d\n",ans[i]);       }       return 0;}