首先考虑,对于前十八个点,我们只需要暴力去查找,去算,这样复杂度是的。可以拿到28.57~34.29的好成绩。

考虑满分做法,我们可以将通过不了的分成三类,如图:图片说明

上面的是JOI官方给的图片

第一类是OI小于a的,总分大于c的,第二类是Math小于b的,总分大于c的,第三类是总分小于c的。

很显然,c可以转化成max(c,a+b),因为如果a+b都没有到,说明一定有一科不及格。

回到上面的图,你发现了什么?

显然第一个条件和第二个条件是只能满足一个的,因为如果都满足那么OI和Math一定都不及格,而这不符合任意一个。

我们可以维护两个树状数组,分别记录OI和Math。我们发现只要不满足总分不小于c,那么是一定不合格的,我们只需要检查c,如果发现总分小于c就将小于的从两个树状数组里删掉。

我们可以用lower_bound来实现查找小于c的,到底有多少个。

于是我们就做完了,复杂度显而易见,是O(NlogNlogN)的,第一个log是树状数组的,而第二个log是lower_bound的。

MY CODE:

#include <iostream>
#include <algorithm>
#include <cmath>
#define pus push_back
#define pai pair<int,int>
#define fir first
#define sec second
#define M 1000005
#define Q 1000005
using namespace std;
int n,f,jsq=0;
pai p[M];
int v[M];
int a[Q];
bool cmp(pai x,pai y)
{
    return x.fir+x.sec<y.fir+y.sec;
}
struct nod{
    int a,b,c;
    int d;
}q[Q];
bool compare(nod x,nod y)
{
    return x.c<y.c;
}
int lob(int x)
{
    return lower_bound(v+1,v+jsq+1,x)-v;
    //STL algorithm
}
struct h{
    int t[M*2];
    int s;
    int lowbit(int x)
    {
        return x&(-x);
    }
    void ins(int x,int y)
    {
        while(x<=s)
        {
            t[x]+=y;
            x+=lowbit(x);
        }
    }
    int query(int x)
    {
        int ans=0;
        while(x>0)
        {
            ans+=t[x];
            x-=lowbit(x);
        }
        return ans;
    }
    //树状数组模板
}t[2];
int main()
{
    cin>>n>>f;
    for(int i=1;i<=n;i++)
    {
        cin>>p[i].fir>>p[i].sec;
        v[++jsq]=p[i].fir;
        v[++jsq]=p[i].sec;
        //iostream自带pair
    }
    sort(v+1,v+jsq+1);
     //STL algorithm
    jsq=unique(v+1,v+jsq+1)-v-1;
     //STL algorithm
    t[0].s=t[1].s=jsq;
    sort(p+1,p+n+1,cmp);
    for(int i=1;i<=f;i++)
    {
        cin>>q[i].a>>q[i].b>>q[i].c;
        q[i].c=max(q[i].c,q[i].a+q[i].b);
        q[i].d=i;
        a[i]=n;
    }
    sort(q+1,q+f+1,compare);
    //STL algorithm
    for(int i=1;i<=n;i++)
    {
        t[0].ins(lob(p[i].fir),1);
        t[1].ins(lob(p[i].sec),1);
    }
    int ans=0;
    for(int i=1;i<=f;i++)
    {
        while(ans<n&&p[ans+1].fir+p[ans+1].sec<q[i].c)
        {
            ans++;
            t[0].ins(lob(p[ans].fir),-1);
            t[1].ins(lob(p[ans].sec),-1);
        }
        a[q[i].d]-=ans;
        a[q[i].d]-=t[0].query(lob(q[i].a)-1);
        a[q[i].d]-=t[1].query(lob(q[i].b)-1);
    }
    for(int i=1;i<=f;i++)
    cout<<a[i]<<endl;
    return 0;
}

这一道题,已经把我折磨够了,后两体再补吧awa。。