返回上一页

暑期集训 8.13

题面链接(备用)



A.开根

直接调用库函数,O(1)出结果.(没想到pow居然可以乘小数次方)

代码不放了.

B.迭代

要求的是x进行n-1次 x=x+1x2 操作后的值.

将通式化简,ab+ba2=a2+b22ab .
令其等于 a1b1 ,代表进行1次操作后它的值.

那么显然:

a1+b1=(a+b)2

a1b1=(ab)2

则第二次操作后:

a2+b2=(a1+b1)2=(a+b)4

a2b2=(a1b1)2=(ab)4

推广到第n-1次操作后:

anbn=(a1b1)2n1

那么 f(x) 就可以轻松求出来了.

f(x)=(x+1)2n1+(x1)2n1(x+1)2n1(x1)2n1

这里 2n1 会炸 long long ,需要使用欧拉定理求一下.

点击查看代码
#include<bits/stdc++.h>
#pragma GCC optomize(2)
#define ll long long
#define rg register
#define rll rg ll
#define mod 1000000007
using namespace std;
static inline ll read()
{
	rll f=0,x=0;rg char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return f?-x:x;
}
static inline void write(rll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);putchar(x%10|48);
}
ll t,x,n,fz,fm;
static inline ll ksm(rll a,rll b,rll p)
{
	rll ans=1;a%=p;
	for(rll i=b;i;i>>=1)
	{
		if(i&1) ans=ans*a%p;
		a=a*a%p;
	}
	return ans;
}
int main()
{
	t=read();
	while(t--)
	{
		x=read();n=read();
		fz=(ksm(x+1,ksm(2,n-1,mod-1),mod)+ksm(x-1,ksm(2,n-1,mod-1),mod))%mod;
		fm=(ksm(x+1,ksm(2,n-1,mod-1),mod)-ksm(x-1,ksm(2,n-1,mod-1),mod)+mod)%mod;
		write(fz*ksm(fm,mod-2,mod)%mod);puts("");
	}
	return 0;
}

C.致富之路

题解很详细了,依照它模拟即可. 假如选定第 i 家工厂与第 j 家商店,那么获利为 max(qjpi,0)×max(ejdi,0) . 对于两家工厂 i,j ,如果 pipjdidj ,那么显然没有选 j 的必要。 将工厂按 p 从小到大排序,对于 p 相同的情况,保留 d 最 小的工厂。 按 p 从小到大考虑每个工厂,如果它的 d 比之前所有工厂 都要小,那么保留。 如此一来,有 pidi+1 恒成立。

对于商店也是类似的道理。 对于两家商店 i,j
,如果 qiqjeiej ,那么显然没有选 i 的必要。 将商店按 q 从小到大排序,对于 q 相同的情况,保留 e 最 大的商店。 按 q 从小到大考虑每个商店,维护一个 e 单调递减的栈, 将不满足 e 递减性质的商店剔除。 如此一来,也有 qiei+1 恒成立。

假设有两家工厂 j<k,如果 kj 优,那么有:

(qipj)(eidj)<(qipk)(eidk)

其中 pkpj>0,djdk>0 ,而对于 i 之后的所有商店, e 在减小,而 q 在增加。 故随着 i 的增大,不等式左侧的值只会越来越小,这说明一 旦 kj 优,那么 k 将永远比 j 优。

因此可以利用这种决策单调性,设计分治算法来解决问题。 令 solve(l,r,dl,dr) 表示在 [l,r] 之间选择商店,在 [dl,dr] 之 间选择工厂。 取 mid=l+r2 ,取遍 [dl,dr] 之间所有工厂,选取对商店 mid 最优的工厂 dm . 那么对于 [l,mid) 的商店,它们最优的工厂只能在 [dl,dm] 之间选取。同理对于 (mid,r] 的商店,它们最优的工厂只能 在 [dm,dr] 之间选取。 故 solve(l,mid1,dl,dm)solve(mid+1,r,dm,dr) 即可。

然而这么做是有问题的。 如果对于商店 mid 来说,并不存在一家工厂使得它们之间 的获利为正。 那么此时 mid 并不存在最优决策,不管 dm 取什么都会对 其他商店造成影响。 故在一开始将这种商店直接剔除即可。

对于 l,r 部分,是深度为 O(logm) 的分治。 对于每层来说,所有 solve 过程的 [dl,dr] 区间长度加起来为 O(n) . 故分治部分的时间复杂度为 O(nlogm) . 总时间复杂度 O(mlogm+nlogn+nlogm) .

点击查看代码
#include<bits/stdc++.h>
#pragma GCC optomize(2)
#define ll long long
#define rg register
#define rll rg ll
#define maxn 500001
#define mod 1000000007
using namespace std;
static inline ll read()
{
	rll f=0,x=0;rg char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return f?-x:x;
}
static inline void write(rll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);putchar(x%10|48);
}
struct node
{
	ll d,p;
	inline friend bool operator<(rg node a,rg node b)
	{
		if(a.p==b.p) return a.d<b.d;
		return a.p<b.p;
	}
}a[maxn],aa[maxn];
struct node1
{
	ll e,q;
	inline friend bool operator<(rg node1 a,rg node1 b)
	{
		if(a.q==b.q) return a.e>b.e;
		return a.q<b.q;
	}
}b[maxn],bb[maxn];
ll cnt1,cnt2,m,n,ans=LLONG_MIN;
deque<ll> s;
static inline void solve(rll l,rll r,rll dl,rll dr)
{
	if(l>r) return;
	rll mid=(l+r)>>1,mx=LLONG_MIN,dm=0;
	for(rll i=dl;i<=dr;i++) if((b[mid].q-a[i].p)*(b[mid].e-a[i].d)>mx) mx=(b[mid].q-a[i].p)*(b[mid].e-a[i].d),dm=i;
	if(mx<0) return;
	ans=max(ans,mx);
	solve(l,mid-1,dl,dm);solve(mid+1,r,dm,dr);
}
int main()
{
	cnt1=read();n=read();
	for(rll i=1;i<=cnt1;i++) aa[i].p=read(),aa[i].d=read();
	sort(aa+1,aa+cnt1+1);
	for(rll i=1;i<=cnt1;i++) if(aa[i].p!=aa[i-1].p) a[++m]=aa[i];
	for(rll i=1;i<=n;i++) b[i].q=read(),b[i].e=read();
	sort(b+1,b+n+1);
	for(rll i=1;i<=n;i++) if(b[i].q!=b[i-1].q) bb[++cnt2]=b[i];
	for(rll i=1;i<=cnt2;i++)
	{
		while((!s.empty())&&bb[i].e>=bb[s.back()].e) s.pop_back();
		s.push_back(i);
	}
	n=0;
	while(!s.empty()) b[++n]=bb[s.front()],s.pop_front();
	solve(1,n,1,m);
	write(ans);
	return 0;
}

然后你就有了90分的好成绩.

运行编号用户问题结果内存耗时语言代码长度提交时间
1073718hszx0119答案错误90
37140
777
C++/Edit2783 B2022-08-13 16:23:13admin

然后是一波玄学更改.

把sort的顺序改一下(商店的都改成倒序排列),solve时商店和工厂反过来,然后就......AC了???

运行编号用户问题结果内存耗时语言代码长度提交时间
1073964hszx0119正确
36884
2068
C++/Edit3642 B2022-08-13 17:39:27admin
点击查看代码
#include<bits/stdc++.h>
#pragma GCC optomize(2)
#define ll long long
#define rg register
#define rll rg ll
#define maxn 500001
#define mod 1000000007
using namespace std;
static inline ll read()
{
	rll f=0,x=0;rg char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return f?-x:x;
}
static inline void write(rll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);putchar(x%10|48);
}
struct node
{
	ll d,p;
	inline friend bool operator<(rg node a,rg node b)
	{
		if(a.p==b.p) return a.d<b.d;
		return a.p<b.p;
	}
}a[maxn],aa[maxn];
struct node1
{
	ll e,q;
	inline friend bool operator<(rg node1 a,rg node1 b)
	{
		if(a.q==b.q) return a.e>b.e;
		return a.q>b.q;
		//关于倒序排列,dalao是这么证明的:=的时候不满足决策单调性,-1排除了等于的情况
	}
}b[maxn],bb[maxn];
ll cnt1,cnt2,m,n,ans=LLONG_MIN;
ll mx[maxn];
deque<ll> s;
static inline void solve(rll l,rll r,rll dl,rll dr)
{
	if(l>r) return;
	rll mid=(l+r)>>1,dm=0;
	for(rll i=dl;i<=dr;i++)
	{
		if(b[i].e<a[mid].d&&b[i].q<a[mid].p) continue;//只是更改了一下判断方式,和前面的操作相同
		if((b[i].q-a[mid].p)*(b[i].e-a[mid].d)>mx[mid]) mx[mid]=(b[i].q-a[mid].p)*(b[i].e-a[mid].d),dm=i;
	}
	ans=max(ans,mx[mid]);
	solve(l,mid-1,dl,dm);solve(mid+1,r,dm,dr);
}
int main()
{
	m=read();n=read();
	for(rll i=1;i<=m;i++) a[i].p=read(),a[i].d=read();
	sort(a+1,a+m+1);rll mn=LLONG_MAX,ls;
	for(rll i=1;i<=m;)//只是更改了一下更新方式,和前面的操作相同
	{
		if(a[i].d<mn) mx[cnt1++]=LLONG_MIN,mn=a[i].d,a[cnt1]=a[i];
		ls=a[i].p;
		while(a[i].p==ls&&i<=m) i++;
	}a[++m]=aa[s.front()],s.pop_front();
	for(rll i=1;i<=n;i++) b[i].q=read(),b[i].e=read();
	sort(b+1,b+n+1);rll mx=LLONG_MIN;
	for(rll i=1;i<=n;)//只是更改了一下更新方式,和前面的操作相同
	{
		if(b[i].e>mx) mx=b[i].e,b[++cnt2]=b[i];
		ls=b[i].q;
		while(b[i].q==ls&&i<=n) i++;
	}	while((!s.empty())&&bb[i].e>=bb[s.back()].e) s.pop_back();
	solve(1,m=cnt1,1,n=cnt2);
	write(ans);
	return 0;
}


未完待续......

posted @   1Liu  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示