2025年寒假算法天梯赛 06

B. clay17与segMilkTrea

  • 类型数的统计并没有很巧妙高效的方案,就是朴素地用桶维护。所以可以考虑朴素地求出一轮的方案,再通过数据结构维护快速地过渡到下一轮。
  • 线段树的标记一定是具有可加性的
#include <bits/stdc++.h>
using namespace std;
const int mod=998244353;
long long inv[1000005];
int power(int n,int p)
{
	if(p==0)
	{
		return 1;
	}
	long long tmp=power(n,p/2);
	if(p%2==1)
	{
		return tmp*tmp%mod*n%mod;
	}
	return tmp*tmp%mod;
}
int n,a[1000005],raw[1000005];
map<int,int>v;
long long s[1000005];
int h[1000005],cur[1000005],nx[1000005];
struct t1
{
	int l,r;
	long long v;
	int bj;
}t[4000005];
void build(int p,int l,int r)
{
	t[p].l=l;
	t[p].r=r;
	t[p].bj=0;
	if(l==r)
	{
		t[p].v=s[l];
		return;
	}
	int mid=(l+r)>>1;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	t[p].v=(t[p*2].v+t[p*2+1].v)%mod;
}
void spread(int p)
{
	if(t[p].bj)
	{
		t[p*2].bj+=t[p].bj;
		t[p*2+1].bj+=t[p].bj;
		(t[p*2].v*=inv[t[p].bj])%=mod;
		(t[p*2+1].v*=inv[t[p].bj])%=mod;
		t[p].bj=0;
	}
}
void change(int p,int l,int r)
{
	if(l<=t[p].l&&r>=t[p].r)
	{
		(t[p].v*=inv[1])%=mod;
		t[p].bj++;
		return;
	}
	spread(p);
	int mid=(t[p].l+t[p].r)>>1;
	if(l<=mid)
	{
		change(p*2,l,r);
	}
	if(r>mid)
	{
		change(p*2+1,l,r);
	}
	t[p].v=(t[p*2].v+t[p*2+1].v)%mod;
}
int ask(int p,int l,int r)
{
	if(l<=t[p].l&&r>=t[p].r)
	{
		return t[p].v;
	}
	spread(p);
	int mid=(t[p].l+t[p].r)>>1;
	long long va=0;
	if(l<=mid)
	{
		va+=ask(p*2,l,r);
	}
	if(r>mid)
	{
		va+=ask(p*2+1,l,r);
	}
	return va%mod;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	inv[1]=power(2,998244351);
	for(int i=2;i<=1000000;i++)
	{
		inv[i]=inv[i-1]*inv[1]%mod;
	}
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		raw[i]=a[i];
	}
	sort(raw+1,raw+n+1);
	int m=unique(raw+1,raw+n+1)-(raw+1);
	for(int i=1;i<=m;i++)
	{
		v[raw[i]]=i;
	}
	for(int i=1;i<=n;i++)
	{
		a[i]=v[a[i]];
		nx[cur[a[i]]]=i;
		cur[a[i]]=i;
	}
	long long sum=0;
	int cnt=0;
	for(int j=1;j<=n;j++)
	{
		if(!h[a[j]])
		{
			cnt++;
		}
		h[a[j]]++;
		s[j]=power(2,cnt);
		sum=(sum+s[j])%mod;
	}
	build(1,1,n);
	for(int i=1;i<n;i++)
	{
		h[a[i]]--;
		if(h[a[i]]==0)
		{
			change(1,i+1,n);
		}
		else
		{
			if(i+1<=nx[i]-1)
			{
				change(1,i+1,nx[i]-1);
			}
		}
		sum=(sum+ask(1,i+1,n))%mod;
	}
	cout<<sum<<endl;
	return 0;
}

C. 机器人仓库

  • 切比雪夫距离看似很抽象,其实就是允许斜走的路径距离
  • \((x,y)\to(\frac{x+y}{2},\frac{x-y}{2}):\)切比雪夫距离转曼哈顿距离
  • \((x,y)\to(x+y,x-y):\)曼哈顿距离转切比雪夫距离
  • 直接➗2可能存在下取整的问题,可以等到最后统一➗2
  • 求到数轴上各点距离和最小的点,其实是中位数问题
#include <bits/stdc++.h>
using namespace std;
struct t1
{
	int x,y;
	long long t;
}t[100005];
int n;
long long calc(int x,int y)
{
	long long res=0;
	for(int i=1;i<=n;i++)
	{
		res=res+max(abs(t[i].x-x),abs(t[i].y-y))*t[i].t;
	}
	return res;
}
typedef pair<int,int> pii;
vector<pii>a,b;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n;
	double X=0,Y=0;
	long long sum=0;
	for(int i=1;i<=n;i++)
	{
		cin>>t[i].x>>t[i].y>>t[i].t;
		a.push_back(pii(t[i].x+t[i].y,t[i].t));
		b.push_back(pii(t[i].x-t[i].y,t[i].t));
		sum+=t[i].t;
	}
	long long cur=0;
	sort(a.begin(),a.end());
	for(int i=0;i<a.size();i++)
	{
		cur+=a[i].second;
		if(cur*2>=sum)
		{
			X=a[i].first/2.0;
			break;
		}
	}
	sort(b.begin(),b.end());
	cur=0;
	for(int i=0;i<b.size();i++)
	{
		cur+=b[i].second;
		if(cur*2>=sum)
		{
			Y=b[i].first/2.0;
			break;
		}
	}
	int x=(int)(X+Y),y=(int)(X-Y);
	long long minn=LLONG_MAX;
	int p=-1,q=-1;
	int w=ceil(sqrt(1000000000/n))/2;
	for(int i=max(x-w,1);i<=max(x-w,1)+2*w;i++)
	{
		for(int j=max(y-w,1);j<=max(y-w,1)+2*w;j++)
		{
			long long res=calc(i,j);
			if(res<minn||res==minn&&i+j<p+q)
			{
				minn=res;
				p=i;
				q=j;
			}
		}
	}
	cout<<p<<" "<<q<<endl;
	return 0;
}
posted @ 2025-02-14 20:56  D06  阅读(17)  评论(0)    收藏  举报
//雪花飘落效果