就是线段树维护区间最大值。
先对背包容量从小到大排序,然后每次都去线段树中找能不能放入背包的最大值,然后取走标记成很小的数。思有错吗?
只有24分
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
#define For(i,a,b) for ( register int i=(a);i<=(b);i++ )
#define Dow(i,b,a) for ( register int i=(b);i>=(a);i-- )
#define GO(i,x) for ( int i=head[x];i;i=e[i].nex )
#define mem(x,s) memset(x,s,sizeof(x))
#define cpy(x,s) memcpy(x,s,sizeof(x))
#define YES return puts("YES"),0
#define NO return puts("NO"),0
#define GG return puts("-1"),0
#define pb push_back
#define lowbit(x) x&(-x)
#define int long long
using namespace std;
inline int read()
{
int sum=0; char ch=getchar();
while(!isdigit(ch))
ch=getchar();
while(isdigit(ch))
sum=sum*10+(ch^48),ch=getchar();
return sum;
}
const int mod=1e9+7;
const int mo=998244353;
const int N=1e6+5;
const int M=1005;
inline int min(int x,int y) {if(x<y) return x; return y;}
inline int max(int x,int y) {if(x>y) return x; return y;}
int n,m,C[N],t[N*2],tmp[N*2],ans;
struct Node
{
int x,y;
inline bool friend operator < (const Node &a,const Node &b)
{
if(a.x^b.x) return a.x<b.x;
return a.y>b.y;
}
};
Node a[N];
vector<int> G[N];
inline void build(int x,int l,int r)
{
if(l==r)
{
t[x]=a[l].y;
return;
}
int mid=(l+r)/2;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
t[x]=max(t[x<<1],t[x<<1|1]);
}
inline void fix(int x,int l,int r,int p,int val)
{
if(l==r)
{
t[x]=val;
return;
}
int mid=(l+r)/2;
if(p<=mid) fix(x<<1,l,mid,p,val);
else fix(x<<1|1,mid+1,r,p,val);
t[x]=max(t[x<<1],t[x<<1|1]);
}
inline int ask(int x,int l,int r,int ll,int rr)
{
if(ll<=l&&r<=rr) return t[x];
int mid=(l+r)/2,ans=0;
if(ll<=mid) ans=ask(x<<1,l,mid,ll,rr);
if(rr>mid) ans=max(ans,ask(x<<1|1,mid+1,r,ll,rr));
return ans;
}
signed main()
{
n=read(),m=read();
For(i,1,n)
{
int x,y;
x=read(),y=read();
a[i]=(Node){x,y};
}
sort(a+1,a+n+1);
For(i,1,n) G[a[i].y].pb(i);
For(i,1,m) C[i]=read();
sort(C+1,C+m+1);
int l=0,r=n,mp=0;
while(l<=r)
{
int mid=(l+r)/2;
if(a[mid].x<=C[m])
l=mid+1,mp=mid;
else r=mid-1;
}
if(!mp) return puts("0"),0;
build(1,1,mp);
For(i,1,mp) tmp[i]=a[i].x;
int ans=0;
For(i,1,m)
{
int x=upper_bound(tmp+1,tmp+mp+1,C[i])-tmp-1;
int s=ask(1,1,mp,1,x);
int P=0;
For(j,0,G[s].size()-1)
{
int v=G[s][j];
if(v<=x)
{
P=v;
break;
}
}
fix(1,1,mp,P,-10000000);
ans+=s;
}
printf("%lld\n",ans);
return 0;
}