loj6270

#6270. 数据结构板子题

sol:对于一个询问L,R,Limit,答案就是所有长度小于R-l+1的线段-长度小于Limit的线段-左端点在L左边的线段-右端点在R右边的线段,求这个东西

后面两个东西可以十分容易的用两棵树状数组维护,但是直接搞得话长度小于Limit且不在区间[L,R]中的区间会被减两遍,把他们加上去即可

#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline char gc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
#define getchar gc
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch=' ';
    while(!isdigit(ch))
    {
        f|=(ch=='-'); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-'); x=-x;
    }
    if(x<10)
    {
        putchar(x+'0');    return;
    }
    write(x/10);
    putchar((x%10)+'0');
    return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('
')
const int N=500005;
int n,Q,ans[N];
struct Question
{
    int l,r,Down,Id;
}Ques[N];
vector<int>Limit1[N],Limit2[N];
struct Xianduan
{
    int l,r,Len;
    inline bool operator<(const Xianduan &tmp)const
    {
        return Len<tmp.Len;
    }
}Line[N<<1];
struct BIT
{
    int S[N];
    #define lowbit(x) ((x)&(-x))
    inline void Ins(int x)
    {
        for(;x<=n;x+=lowbit(x))
        {
            ++S[x];
        }
    }
    inline int Que(int x)
    {
        int Sum=0;
        for(;x;x-=lowbit(x))
        {
            Sum+=S[x];
        }
        return Sum;
    }
}T1,T2;
int main()
{
    register int i,j;
    R(n); R(Q);
    for(i=1;i<=n;i++)
    {
        R(Line[i].l); R(Line[i].r);
        Line[i].Len=Line[i].r-Line[i].l;
    }
    sort(Line+1,Line+n+1);
    for(i=1;i<=Q;i++)
    {
        R(Ques[i].l); R(Ques[i].r); R(Ques[i].Down); Ques[i].Id=i;
        if(Ques[i].r-Ques[i].l>=Ques[i].Down)
        {
            Limit1[Ques[i].Down-1].push_back(i);
            Limit2[Ques[i].r-Ques[i].l+1].push_back(i);
        }
    }
    register int Pos=1,tot=0;
    for(i=1;i<=n;i++) //枚举线段长度
    {
        while(Pos<=n&&Line[Pos].Len==i)
        {
            T1.Ins(Line[Pos].l);
            T2.Ins(Line[Pos].r);
            ++tot; ++Pos;
        }
        for(j=0;j<Limit1[i].size();j++)
        {
            register int o=Limit1[i][j];
            ans[o]=ans[o]-tot+T1.Que(Ques[o].l-1)+(tot-T2.Que(Ques[o].r));
        }
        for(j=0;j<Limit2[i].size();j++)
        {
            register int o=Limit2[i][j];
            ans[o]=ans[o]+tot-T1.Que(Ques[o].l-1)-(tot-T2.Que(Ques[o].r));
        }
    }
    for(i=1;i<=Q;i++) Wl(ans[i]);
    return 0;
}
/*
input
5 5
1 2
1 3
2 3
2 4
2 5
1 5 1
1 4 1
1 5 2
2 5 2
1 5 3
output
5
4
3
2
1
*/
View Code
原文地址:https://www.cnblogs.com/gaojunonly1/p/10724107.html