线段树做法为什么有问题
查看原帖
线段树做法为什么有问题
308464
奇米楼主2020/7/11 20:40

就是线段树维护区间最大值。

先对背包容量从小到大排序,然后每次都去线段树中找能不能放入背包的最大值,然后取走标记成很小的数。思有错吗?

只有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;
}
	 
	
 

2020/7/11 20:40
加载中...