HDU---4417Super Mario 树状数组 离线操作

题意:给定 n个数,查询 位置L R内 小于x的数有多少个。

对于某一次查询 把所有比x小的数 ”的位置“ 都加入到树状数组中,然后sum(R)-sum(L-1)就是答案,q次查询就要离线操作了,按高度排序。

#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
template <class T>
inline bool scan_d(T &ret)
{
    char c;
    int sgn;
    if(c=getchar(),c==EOF)
    return 0;
    while(c!='-'&&(c<'0'||c>'9'))     c=getchar();
    sgn = (c=='-')?-1:1;
    ret =(c=='-')?0:(c-'0');
    while(c=getchar(),c>='0'&&c<='9')     ret=ret*10+(c-'0');
    ret*=sgn;
    return 1;
}
const int maxn = 1e5+100;
int n,q,c[maxn];
int lowbit (int x)
{
    return x & -x;
}
void add(int x,int d)
{
    while (x <= n)
    {
        c[x] += d;
        x += lowbit(x);
    }
}
int sum(int x)
{
    int ans = 0;
    while (x > 0)
    {
        ans += c[x];
        x -= lowbit(x);
    }
    return ans;
}
struct Node1
{
    int v,index;
}h[maxn];
struct Node2
{
    int l,r,v,index,ans;
}H[maxn];
bool cmp1(const Node1 &n1,const Node1 &n2)
{
    return n1.v < n2.v;
}
bool cmp2(const Node2 &n1,const Node2 &n2)
{
    return n1.v < n2.v;
}
bool cmp3(const Node2 &n1,const Node2 &n2)
{
    return n1.index < n2.index;
}
int main(void)
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    #endif
    int t,cas = 1;
     scanf ("%d",&t);
    while (t--)
    {
        memset(c,0,sizeof(c));
        scanf ("%d%d",&n,&q);
        for (int i = 1; i <= n; i++)
        {
            scanf ("%d",&h[i].v);
            h[i].index = i;
        }
        sort(h+1,h+n+1,cmp1);
        for (int i = 1; i <= q; i++)
        {
            scanf ("%d%d%d",&H[i].l,&H[i].r,&H[i].v);
            H[i].l++;
            H[i].r++;
            H[i].index = i;
        }
        sort(H+1,H+q+1,cmp2);
        int j = 1;
        for (int i = 1; i <= q; i++)
        {
            int tmp = H[i].v;
            while (h[j].v <= tmp&&j<=n)      //这里要加j<=n 不然会死循环
            {
                add(h[j].index,1);
                j++;
            }
            H[i].ans = sum(H[i].r) - sum(H[i].l-1);
        }
        sort(H+1,H+q+1,cmp3);
        printf("Case %d:\n",cas++);
        for (int i = 1; i <= q; i++)
        {
            printf("%d\n",H[i].ans);
        }
    }
    return 0;
}
View Code

 

posted @ 2014-10-14 20:31  PlasticSpirit  阅读(122)  评论(0编辑  收藏  举报