SDUT oj 2610

  1 /*题目大意:输入一序列n个数字,然后输入m个询问,每个询问包含左边区间和右边区间,还有a和b,问你这个区间内有几个数大于等于a且小于等于b
  2 做法:树状数组,先求出这个区间内有几个数小于a,然后求这个区间内有几个数小于等于b,拿后者减去前者就是答案了*/
  3 #include<stdio.h>
  4 #include<string.h>
  5 #include<algorithm>
  6 using namespace std;
  7 const int maxn=50010;
  8 int c[maxn],ansl[maxn],ansr[maxn];
  9 struct pp
 10 {
 11     int num;
 12     int id;
 13 }p[maxn];
 14 struct p2p
 15 {
 16     int hi;
 17     int id;
 18     int l,r;
 19     int low;
 20 }p1[maxn];
 21 int cmp(pp a,pp b)
 22 {
 23         return a.num<b.num;
 24 }
 25 int cmp1(p2p a,p2p b)
 26 {
 27     return a.low<b.low;
 28 }
 29 int cmp2(p2p a,p2p b)
 30 {
 31     return a.hi<b.hi;
 32 }
 33 int n,m;
 34 int lowbit(int x)
 35 {
 36     return x&(-x);
 37 }
 38 void add(int x,int d)
 39 {
 40     while(x<=n)
 41     {
 42         c[x]+=d;
 43         x=x+lowbit(x);
 44     }
 45 }
 46 int sum(int x)
 47 {
 48     int ans=0;
 49     while(x>0)
 50     {
 51         ans+=c[x];
 52         x=x-lowbit(x);
 53     }
 54   return ans;
 55 }
 56 int main()
 57 {
 58     int i,j,k;
 59     int t;
 60     int cas=0;
 61     scanf("%d",&t);
 62     while(t--)
 63     {
 64         memset(c,0,sizeof(c));
 65         memset(ansl,0,sizeof(ansl));
 66         scanf("%d%d",&n,&m);
 67         for(i=1;i<=n;i++)
 68         {
 69             scanf("%d",&p[i].num);
 70             p[i].id=i;
 71         }
 72         for(i=1;i<=m;i++)
 73         {
 74             scanf("%d%d%d%d",&p1[i].l,&p1[i].r,&p1[i].low,&p1[i].hi);
 75             p1[i].id=i;
 76         }
 77         sort(p+1,p+n+1,cmp);
 78         sort(p1+1,p1+m+1,cmp1);
 79         i=1;
 80         j=1;
 81        while(j<=m)
 82       {
 83           while(i<=n)
 84           {
 85             if(p[i].num>=p1[j].low)
 86             break;
 87             add(p[i].id,1);
 88             i++;
 89           }
 90          while(j<=m)
 91          {
 92           if(i<=n&&p[i].num<p1[j].low)
 93           break;
 94           ansl[p1[j].id]=sum(p1[j].r)-sum(p1[j].l-1);
 95           j++;
 96          }
 97       }
 98       i=1;
 99       j=1;
100       memset(c,0,sizeof(c));
101       memset(ansr,0,sizeof(ansr));
102       sort(p1+1,p1+m+1,cmp2);
103       while(j<=m)
104       {
105           while(i<=n)
106           {
107             if(p[i].num>p1[j].hi)
108             break;
109             add(p[i].id,1);
110             i++;
111           }
112          while(j<=m)
113          {
114           if(i<=n&&p[i].num<=p1[j].hi)
115           break;
116           ansr[p1[j].id]=sum(p1[j].r)-sum(p1[j].l-1);
117           j++;
118          }
119       }
120       printf("Case #%d:\n",++cas);
121       for(i=1;i<=m;i++)
122           if(ansr[i]-ansl[i]>0)
123           printf("%d\n",ansr[i]-ansl[i]);
124           else printf("0\n");
125     }
126     return 0;
127 }

 

posted on 2013-08-16 22:06  ok_boy  阅读(382)  评论(0编辑  收藏  举报

导航