[线段树+离线处理] upcoj 2224 Boring Counting

题意:

给N个数,M次询问,每次询问区间[L,R]内元素在[X,Y]内的个数。

思路:

和之前hdu4417一样,这里因为有要在[X,Y]区间内。

所以做两次求出[1,Y]和[1,X-1]内的元素个数,然后相减得出答案。

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
#include"map"
#include"vector"
#define ll long long
using namespace std;
struct quary
{
    int id,x,y,c,d;
} q[110000];
struct fuck
{
    int id,s;
} v[105666];
struct node
{
    int l,r;
    int sum;
} a[200031*4];
int mark[200021],ans[105555][2];
int cmp(fuck a,fuck b)
{
    return a.s<b.s;
}
int cmp1(quary a,quary b)
{
    return a.d<b.d;
}
int cmp2(quary a,quary b)
{
    return a.c<b.c;
}
void init(int id,int l,int r)
{
    a[id].l=l;
    a[id].r=r;
    a[id].sum=0;
    if(l==r) return ;
    int mid=(l+r)/2;
    init(id*2,l,mid);
    init(id*2+1,mid+1,r);
}
void updata(int id,int x,int y)
{
    if(a[id].l==a[id].r && a[id].l==x)
    {
        a[id].sum+=y;
        return ;
    }
    int mid=(a[id].l+a[id].r)/2;
    if(x<=mid) updata(id*2,x,y);
    else updata(id*2+1,x,y);
    a[id].sum=a[2*id].sum+a[2*id+1].sum;
}
int qcont(int id,int x,int y)
{
    if(a[id].l==x && a[id].r==y) return a[id].sum;
    int mid=(a[id].l+a[id].r)/2;
    if(y<=mid) return qcont(2*id,x,y);
    else if(x>mid) return qcont(2*id+1,x,y);
    else return qcont(2*id,x,mid)+qcont(2*id+1,mid+1,y);
}
int main()
{
    int t,cas=1;
    cin>>t;
    while(t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&v[i].s);
            v[i].id=i;
        }
        for(int i=0; i<m; i++)
        {
            scanf("%d%d%d%d",&q[i].x,&q[i].y,&q[i].c,&q[i].d);
            q[i].id=i;
        }
        sort(v+1,v+1+n,cmp);
        sort(q,q+m,cmp1);
        init(1,1,n);
        int j=1;
        for(int i=0; i<m; i++)
        {
            while(j<=n && v[j].s<=q[i].d)
            {
                updata(1,v[j].id,1);
                j++;
            }
            ans[q[i].id][0]=qcont(1,q[i].x,q[i].y);
        }
        sort(q,q+m,cmp2);
        init(1,1,n);
        j=1;
        for(int i=0; i<m; i++)
        {
            while(j<=n && v[j].s<q[i].c)
            {
                updata(1,v[j].id,1);
                j++;
            }
            ans[q[i].id][1]=qcont(1,q[i].x,q[i].y);
        }
        printf("Case #%d:\n",cas++);
        for(int i=0; i<m; i++) printf("%d\n",ans[i][0]-ans[i][1]);
    }
    return 0;
}
时间: 2024-08-30 08:36:11

[线段树+离线处理] upcoj 2224 Boring Counting的相关文章

UPC 2224 Boring Counting (离线线段树,统计区间[l,r]之间大小在[A,B]中的数的个数)

题目链接:http://acm.upc.edu.cn/problem.php?id=2224 题意:给出n个数pi,和m个查询,每个查询给出l,r,a,b,让你求在区间l~r之间的pi的个数(A<=pi<=B,l<=i<=r). 参考链接:http://www.cnblogs.com/zj62/p/3558967.html #include <iostream> #include <cstdio> #include <cstring> #incl

Super Mario(线段树离线区间k值)

以前见过这题,没做出来,知道是离线处理,这次仔细想了下, 首先把出现的高度都map离散化一下,以离散化出来的数目g建树,把每个位置都开俩个vector,一个存以这个位置为L的询问,一个存以这个位置为R的询问. 然后从1-g 进行更新,假如当前i是以第j个区间的开始位置,那么这时就可以询问一下<=p[j].h的个数s,显然这时第J个区间多加的,需要减掉,p[j].sum-=s; 然后更新第i个数,update(a[i],1,g,1);再找到某第k区间是以i结尾的,那么依旧询问一下,得出s,p[k]

线段树+离线 hdu5654 xiaoxin and his watermelon candy

传送门:点击打开链接 题意:一个三元组假设满足j=i+1,k=j+1,ai<=aj<=ak,那么就好的.如今告诉你序列.然后Q次询问.每次询问一个区间[l,r],问区间里有多少个三元组满足要求 思路:刚開始看错题目了,原来三元组是连续3个,这作为bc最后一题也太水了把. . . 先一遍预处理.把连续3个满足条件的找出来,放到还有一个数组里排序去重,用这个数组来给三元组哈希.再扫一遍给三元组在之前那个排序好的数组里二分一下得到下标,大概就是哈希一下,用一个数字来表示. 之后的查询.事实上就是.在

gcd(线段树离线处理)——HDU 4630

对应HDU题目:点击打开链接 No Pain No Game Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1801    Accepted Submission(s): 770 Problem Description Life is a game,and you lose it,so you suicide. But you can

SPOJ--K-query (线段树离线) 离线操作解决一下问题

K-query Given a sequence of n numbers a1, a2, ..., an and a number of k- queries. A k-query is a triple (i, j, k) (1 ≤ i ≤ j ≤ n). For each k-query (i, j, k), you have to return the number of elements greater than k in the subsequence ai, ai+1, ...,

51nod 1463 找朋友(线段树+离线处理)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1463 题意: 思路: 好题! 先对所有查询进行离线处理,按照右区间排序,因为k一共最多只有10个,所有在该区间内的B数组,每次枚举K值,通过这样的方式来得到另外一个B值.但是这样得到的B值它在B数组中的位置必须在当前数的左边.如下图:(j为当前数在B数组中的位置,pos为计算得到的另一个B值在数组中的位置) 这两个数的和记录在pos中,这里pos的位置必须在j的左边,假

玲珑oj 1117 线段树+离线+离散化,laz大法

1117 - RE:从零开始的异世界生活 Time Limit:1s Memory Limit:256MByte Submissions:438Solved:68 DESCRIPTION 486到了异世界,看到了一群可爱的妹子比如蕾姆啊,艾米莉亚啊,拉姆啊,白鲸啊,怠惰啊等等!有一天膜女告诉486说她的能力可能不能再用了,因为膜女在思考一个数据结构题,没心情管486了.486说我来帮你做,膜女说你很棒棒哦! 给一个集合,最开始为空(不是数学上的集合)五个操作: 1.插入x2.把小于x的数变成x3

HDU3874 线段树 + 离线处理

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3874 , 线段树(或树状数组) + 离线处理 下午做了第一道离线处理的题目(HDU4417),多少有点感觉,顺便就把这道题也给做了. 这道题就是要求某个区间内不重复数的和,自己在网上百度后参考别人的方法才AC的.参考来源:http://www.cnblogs.com/gj-Acit/p/3249827.html 这道题还是需要先离线处理数据,具体方法: ① 先用线段树把树给建立起来: ② 先把所有要

HDU4417 线段树 + 离线处理

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 , 线段树(或树状数组) + 离线处理 最近看了几道线段树的题都是需要离线处理数据的,正好这块比较手生,就练练了.  这道题主要的地方就是离线处理数据,具体想法: ① 先把所有位置的高度都存下来,然后排序,注意保存下标: ② 把所有询问存下来,然后按照询问的高度进行排序,同注意保存下标: ③ 对于排序后的每次询问的处理:由于每个位置的高度都已经存了下来并且进行了排序,所以可以按照顺序将每个点插