cf369E 树状数组解决区间包含区间(好题)

思路:减法思想

http://codeforces.com/problemset/problem/369/E

//#pragma comment(linker, "/STACK:102400000")
#include<cstdlib>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<vector>
#define tree int o,int l,int r
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define lo o<<1
#define ro o<<1|1
#define pb push_back
#define mp make_pair
#define ULL unsigned long long
#define LL long long
#define inf 0x7fffffff
#define eps 1e-7
#define N 300009
using namespace std;
int m,n,T,t,x,y,u;
struct Node
{
    int l,r,type;
    bool operator<(const Node& a)const
    {
        return r<a.r||(r==a.r&&type<a.type);
    }
} node[N*4];
int ans[N];
int c[(int)1e6+9];
void add(int x)
{
    while(x<1e6+1)
    {
        c[x]++;
        x+=(x&-x);
    }
}
int sum(int x)
{
    int ans=0;
    while(x>0)
    {
        ans+=c[x];
        x-=(x&-x);
    }
    return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("ex.in","r",stdin);
#endif
    while(scanf("%d%d",&n,&m)==2)
    {
        memset(c,0,sizeof(c));

        int nn=n;
        for(int i=0; i<n; i++)
        {
            scanf("%d%d",&node[i].l,&node[i].r);
            node[i].type=-1;
        }
        for(int i=0; i<m; i++)
        {
            ans[i]=n;
            int p,x,cnt;
            scanf("%d%d",&cnt,&p);
            cnt--;
            if(p>1)
            {
                node[nn].l=1;
                node[nn].r=p-1;
                node[nn++].type=i;
            }
            while(cnt--)
            {
                scanf("%d",&x);
                if(p+1!=x)
                {
                    node[nn].l=p+1;
                    node[nn].r=x-1;
                    node[nn++].type=i;
                }
                p=x;
            }
            if(p<1e6)
            {
                node[nn].l=p+1;
                node[nn].r=1e6;
                node[nn++].type=i;
            }
        }
        sort(node,node+nn);
        for(int i=0; i<nn; i++)
        {
            if(node[i].type==-1)
            {
                add(node[i].l);
            }
            else
            {
                ans[node[i].type]-=sum(node[i].r)-sum(node[i].l-1);
            }
        }
        for(int i=0; i<m; i++)
            printf("%d
",ans[i]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/sbaof/p/3454169.html