省选校内模拟D4

tot=30+0+10=40

T1

  • 脑筋急转弯
  • 每一轮有些数会向左移动一格
  • 答案就是max{i-a[i]}

T3

Solution

 

  • 把上面的式子拆开变成
  • F[i]=max{F[j]+Tj*A/D}-Ti*A/D+Bi-A
  • F[i]=max{F[j]+Tj*A/D}-Ti*A/D+Bi
  • 由于把向上取整拆开了
  • 所以Tj的余数不同状态转移方程也不同
  • 根据余数分类,查询时分类讨论

Code


#include<bits/stdc++.h>
#define rep(i,a,b) for(ll i=(a);i<=(b);++i)
#define ll long long
using namespace std;
const ll N=1e6+100;
ll s,t,d,a,n,x,v,j,root,tot=0,cnt=0,minn[N<<2],lc[N<<2],rc[N<<2],pl[N],k[N],b[N],f[N];
void update(ll &o,ll L,ll R,ll x,ll val){
	if(!o)o=++tot;
	ll M=L+R>>1;
	if(L==R){
		minn[o]=min(minn[o],val);
		return;
	}
	if(x<=M)update(lc[o],L,M,x,val);
	else update(rc[o],M+1,R,x,val);
	minn[o]=min(minn[lc[o]],minn[rc[o]]);
}
ll query(ll &o,ll L,ll R,ll ql,ll qr){
	if(!o)return 1e15;
	if(ql<=L&&R<=qr)return minn[o];
	ll M=L+R>>1;
	ll ans=1e15;
	if(ql<=M)ans=min(ans,query(lc[o],L,M,ql,qr));
	if(M<qr)ans=min(ans,query(rc[o],M+1,R,ql,qr));
	return ans;
}
int main()
{
	freopen("reading.in","r",stdin);
	freopen("reading.out","w",stdout);
	memset(f,0x3f,sizeof(f));
	memset(minn,0x3f,sizeof(minn));
	scanf("%lld%lld%lld%lld%lld",&s,&t,&d,&a,&n);
	k[0]=s/d,b[0]=s%d;;
	rep(i,1,n){
		scanf("%lld%lld",&x,&v);
		k[i]=x/d,b[i]=x%d;
		pl[i]=v;
	}
	k[++n]=t/d,b[n]=t%d;
	update(root,0,d-1,b[0],-k[0]*a);
	rep(i,1,n){
		j=query(root,0,d-1,0,b[i]-1);
		f[i]=min(f[i],j+a+k[i]*a-pl[i]);
		j=query(root,0,d-1,b[i],d-1);
		f[i]=min(f[i],j+k[i]*a-pl[i]);
		update(root,0,d-1,b[i],f[i]-a*k[i]);
	}
	cout<<-f[n];
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值