10pts求条orHack
查看原帖
10pts求条orHack
398152
MinimumSpanningTree最小生成树楼主2024/10/8 13:33

AC on #10,其他 WA。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1e5+100;
int n,m,x,y,dp[N],ans,tr[N];
struct node
{
	int val,mi,ma,id;
}a[N];
bool cmp1(node a1,node a2)
{
	return a1.val<a2.val;
}
bool cmp2(node a1,node a2)
{
	return a1.mi<a2.mi;
}
bool cmp3(node a1,node a2)
{
	return a1.id<a2.id;
}
int lowbit(int x)
{
	return x&(-x);
}
void add(int p,int x)
{
	for(int i=p;i<=100000;i+=lowbit(i)) tr[i]=max(tr[i],x);
}
int query(int p)
{
	int s=0;
	for(int i=p;i;i-=lowbit(i)) s=max(s,tr[i]);
	return s;
}
void clr(int p)
{
	for(int i=p;i<=100000;i+=lowbit(i)) tr[i]=0;
}
void cdq(int l,int r)
{
	int mid=(l+r)>>1;
	if(l==r) return;
	cdq(l,mid);
	sort(a+l,a+mid+1,cmp1),sort(a+mid+1,a+r+1,cmp2);
	for(int i=mid+1,j=l;i<=r;i++)
	{
		while(j<=mid&&a[j].val<=a[i].mi) add(a[j].ma,dp[j]),j++;
		dp[i]=max(dp[i],query(a[i].val)+1);
	}
	for(int i=mid+1,j=l;i<=r;i++)
	{
		while(j<=mid&&a[j].val<=a[i].mi) clr(a[j].ma),j++;
	}
	sort(a+mid+1,a+r+1,cmp3);
	cdq(mid+1,r);
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) 
	{
		scanf("%d",&a[i].val);
		dp[i]=1;
		a[i].ma=a[i].mi=a[i].val;
		a[i].id=i;
	}
	while(m--)
	{
		scanf("%d%d",&x,&y);
		a[x].ma=max(a[x].ma,y),a[x].mi=min(a[x].mi,y);
	} 
	cdq(1,n);
	for(int i=1;i<=n;i++) ans=max(ans,dp[i]);
	printf("%d",ans);
	return 0;
}
2024/10/8 13:33
加载中...