• CDOJ 1104 求两个数列的子列的交集 查询区间小于A的数有多少个 主席树


    求两个数列的子列的交集

    Time Limit: 1 Sec  

    Memory Limit: 256 MB

    题目连接

    http://acm.uestc.edu.cn/#/problem/show/1104

    Description

    给两个数列A, B,长度分别为n1, n2,保证A中每个元素互不相同,保证B中每个元素互不相同。。进行Q次询问,每次查找A[l1...r1]和B[l2..r2]的交集 集合 大小是多少。。

    比如 A = {1,2,3,4,5,6,7},B = {7,6,5,4,3,2,1}

    查询A[2..4]和B[3..5]。。A[2..4] = {2,3,4};B[3..5] = {5,4,3},交集为{3,4},大小为2。。

    Input

    第一行输入n1,第二行输入n1个数;同样,第三行输入n2,第四行输入n2个数。

    第五行输入Q。。接下来Q行输入l1, r1, l2, r2。。

    保证 n1, n2, Q在[12×105]范围内,1l1r1n11l2r2n2,然后数在[109109]范围内。。

    Output

    输出Q行,表示答案。。

    Sample Input

    7
    1 2 3 4 5 6 7
    7
    7 6 5 4 3 2 1
    1
    2 4 3 5

    Sample Output

    2

    HINT

    题意

    题解:

    主席树裸题,查询区间小于a的数有多少个就好了

    代码:

    //qscqesze
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <bitset>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    #include <stack>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define maxn 200500
    #define mod 1001
    #define eps 1e-9
    #define pi 3.1415926
    int Num;
    //const int inf=0x7fffffff;
    const ll inf=999999999;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    //*************************************************************************************
    int a[maxn],b[maxn],lb,n,m;
    struct segmenttree
    {
        int l,r,s;
    }tree[maxn*25];
    int node;
    int root[maxn];
    int search(int x)
    {
        int l=0,r=lb,mid;
        while (l<r)
        {
            mid=l+r+1>>1;
            if(b[mid]<=x) l=mid;
            else r=mid-1;
        }
        return l;
    }
    int build(int l,int r)
    {
        int k=++node;
        tree[k].s=0;
        if(l==r) return k;
        int m=l+r>>1;
        if(l<=m) tree[k].l=build(l,m);
        if(r>m) tree[k].r=build(m+1,r);
        return k;
    }
    int change(int rt,int l,int r,int x)
    {
        int k=++node,root=k,mid;
        tree[k]=tree[rt];
        tree[k].s++;
        while (l<r)
        {
            mid=l+r>>1;
            if(x<=mid)
            {
                rt=tree[rt].l;
                tree[k].l=++node;
                k=node;
                tree[k]=tree[rt];
                tree[k].s++;
                r=mid;
            }
            else
            {
                rt=tree[rt].r;
                tree[k].r=++node;
                k=node;
                tree[k]=tree[rt];
                tree[k].s++;
                l=mid+1;
            }
        }
        return root;
    }
    int query(int L,int R,int l,int r,int x)
    {
        int mid,ans=0;
        while (l<r)
        {
            mid=l+r>>1;
            if(mid>=x)
            {
                r=mid;
                L=tree[L].l;
                R=tree[R].l;
            }
            else
            {
                l=mid+1;
                ans+=tree[tree[R].l].s-tree[tree[L].l].s;
                L=tree[L].r;
                R=tree[R].r;
            }
        }
        if(l==r)
        {
            if(x<l) return 0;
            else return ans+tree[R].s-tree[L].s;
        }
    }
    int get(int l,int r,int val)
    {
        val = search(val);
        if(val==0)return 0;
        return query(root[l-1],root[r],1,lb,val);
    }
    int A[maxn];
    int main()
    {
    
        int nn=read();
        for(int i=1;i<=nn;i++)
            A[i]=read();
        sort(A+1,A+nn+1);
        int n=read();
        for(int i=1;i<=n;i++)
        {
            int x=read();
            int l = 1,r = nn;
            while(l<=r)
            {
                int mid = (l+r)>>1;
                if(A[mid]==x)
                {a[i]=x;break;}
                if(A[mid]<x)l=mid+1;
                else r = mid-1;
            }
            if(a[i]==0)a[i]=inf;
        }
        lb=1;
        for(int i=1;i<=n;i++)
            b[i]=a[i];
        lb=1;
        sort(b+1,b+1+n);
        for(int i=2;i<=n;i++)
            if(b[i]!=b[lb])b[++lb]=b[i];
        node = 0;
        root[0]=build(1,lb);
        for(int i=1;i<=n;i++)
            root[i]=change(root[i-1],1,lb,search(a[i]));
        int m=read();
        for(int i=1;i<=m;i++)
        {
            int n1=read(),n2=read(),n3=read(),n4=read();
            printf("%d
    ",get(n3,n4,n2)-get(n3,n4,n1-1));
        }
    }
  • 相关阅读:
    第12组 Alpha事后诸葛亮
    第12组 Alpha冲刺(6/6)
    第12组 Alpha冲刺(5/6)
    2019 SDN上机第4次作业
    2019 SDN阅读作业
    第12组 Alpha冲刺(4/6)
    第12组 Alpha冲刺(3/6)
    第12组 Alpha冲刺(2/6)
    2019 SDN上机第3次作业
    第10组 Alpha冲刺(4/6)
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4790383.html
Copyright © 2020-2023  润新知