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

      题意:

                同上

      题解:

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

HDOJ 4417 - Super Mario 线段树or树状数组离线处理.._第1张图片

                划分树的效率最低...看来划分树的应用范围还是是很有局限性...只在求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 100005
using 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 100005
using 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 200005
using 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;
}



你可能感兴趣的:(HDOJ 4417 - Super Mario 线段树or树状数组离线处理..)