求助 10分,树状数组解法
查看原帖
求助 10分,树状数组解法
672776
XTianShuo楼主2022/10/23 18:27

太惨了,写了一百多行就十分┭┮﹏┭┮

#include<bits/stdc++.h>
using namespace std;

const int N=5e5+10;

int n,m,tot,TOT;
struct dd{
	double x,y,v;
	double ed;
}d[N];
double b[N];
int xc[N],yc[N];
int t1[N],t2[N],sum[N],a[N],deita[N];
vector<int> v[N];

void add(int x)
{
	for(;x;x-=x&-x) t1[x]++;
}
int ask(int x)
{
	int ans=0;
	for(;x<=tot;x+=x&-x) ans+=t1[x];
	return ans;
}

void ADD(int x)
{
	for(;x<=tot;x+=x&-x) t2[x]++;
}
int ASK(int x)
{
	int ans=0;
	for(;x;x-=x&-x) ans+=t2[x];
	return ans;
}

bool CMP(int x,int y)
{
	return d[x].x<d[y].x;
}
bool cmp(int x,int y)
{
	return x>y;
}

int main()
{
//	freopen("1.in","r",stdin);
//	freopen("1.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%lf%lf%lf",&d[i].x,&d[i].y,&d[i].v);
		d[i].ed=d[i].x+d[i].v*sqrt(2.0*d[i].y/9.8);
		b[i]=d[i].y;
	}
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	// y lsh
	sort(b+1,b+1+n);
	tot=unique(b+1,b+1+n)-b-1;
	for(int i=1;i<=n;i++)
		yc[i]=lower_bound(b+1,b+1+tot,d[i].y)-b;
	TOT=tot;
	//x lsh
	for(int i=1;i<=n;i++) b[i]=d[i].ed;
	sort(b+1,b+1+n);
	tot=unique(b+1,b+1+n)-b-1;
	for(int i=1;i<=n;i++)
		xc[i]=lower_bound(b+1,b+1+tot,d[i].ed)-b;
	//push
	for(int i=1;i<=n;i++)
		v[yc[i]].push_back(i);
	for(int i=1;i<=TOT;i++)
		sort(v[i].begin(),v[i].end(),CMP);
	//solution
	int ans=0;
	for(int i=1;i<=TOT;i++)
	{
		int sz=v[i].size();
		for(int j=1;j<=tot;j++) t1[j]=t2[j]=0;
		for(int j=0;j<sz;j++)
		{
		//	cout<<i<<" "<<v[i][j]<<endl;
			add(xc[v[i][j]]);
			int x=ask(xc[v[i][j]]+1);
			sum[v[i][j]]+=x;
		}
		for(int j=sz-1;j>=0;j--)
		{
			ADD(xc[v[i][j]]);
			sum[v[i][j]]+=ASK(xc[v[i][j]]-1);
		}
	}
	for(int i=1;i<=n;i++)
	{
		if(sum[i]<a[i]) deita[i]=sum[i];
		else deita[i]=a[i]-sum[i];
		ans+=sum[i];
		//printf("%d  %d\n",i,sum[i]);
	}
//	cout<<tot<<" "<<TOT<<endl;
	//cout<<ans<<endl;
	sort(deita+1,deita+1+n,cmp);
	for(int i=1;i<=m;i++)
		ans-=deita[i];
	cout<<ans;
	return 0;
}
2022/10/23 18:27
加载中...