(联考)noip93
T1
二分答案。
设二分出来的值为 \(mid\) ,将花费小于mid的所有货币都买,如果总花费大于限制,则考虑去掉第一种中的最大的一个,去掉第二种中的最大的一个,两种都去掉一个这三种情况,取个 \(\max\) 即可。
一些细节见code。
Code
#include<cstdio>
#include<cctype>
#include<iostream>
using std::max;
#define re register
#define long __int128
#define scanf oma=scanf
#define freopen file=freopen
int oma;
FILE* file;
namespace some
{
struct stream
{
template<typename type>inline stream &operator >>(type &s)
{
bool w=0; s=0; char ch=getchar();
while(!isdigit(ch)){ w|=ch=='-'; ch=getchar(); }
while(isdigit(ch)){ s=(s<<1)+(s<<3)+(ch^48); ch=getchar(); }
return s=w?-s:s,*this;
}
}cin;
auto print = [](long x)
{
char ch[20]; int len=0;
if(x<0) x=-x,putchar('-');
do{ ch[len++]=x%10+'0'; x/=10; }while(x);
for(int i=len-1;~i;i--) putchar(ch[i]); printf(" ");
};
int q;
long a,b,c,d,x,l,r;
long res1,res2,res;
#define debug(s) printf("%s\n",s)
}using namespace some;
namespace right
{
auto check = [](long mid) -> bool
{
res1 = (mid-a+b)/b,res2 = (mid-c+d)/d;
if(res1<0) { res1 = 0; }
if(res2<0) { res2 = 0; }
//print(res1),print(res2),debug("");
long w1 = res1*a+res1*(res1-1)/2*b,w2 = res2*c+res2*(res2-1)/2*d;
if(w1+w2<=x)
{ /*debug("shit1");*/ res = max(res,res1+res2); return 1; }
if(res1>0&&w1-a-b*(res1-1)+w2<=x)
{ /*debug("shit2");*/ res = max(res,res1+res2-1); return 1; }
if(res2>0&&w1+w2-c-d*(res2-1)<=x)
{ /*debug("shit3");*/ res = max(res,res1+res2-1); return 1; }
if(res1>0&&res2>0&&w1-a-b*(res1-1)+w2-c-d*(res2-1)<=x)
{ /*debug("shit4"); printf("w1="); print(w1); debug("");*/ res = max(res,res1+res2-2); return 1; }
//debug("shit5");
return 0;
};
auto solve = []() -> void
{
res = 0,l = 1,r = x;
while(l<=r)
{
long mid = l+r>>1;
//printf("l="),print(l),printf("mid="),print(mid),printf("r="),print(r);
if(check(mid))
{ /*debug("nmsl");*/ l = mid+1; /*print(res); debug("");*/ }
else
{ r = mid-1; }
}
print(res); debug("");
};
};
namespace OMA
{
auto main = []() -> signed
{
//#define local
#ifdef local
debug("look here! if you want submit,please closed this");
freopen("node.in","r",stdin); freopen("my.out","w",stdout);
#endif
freopen("money.in","r",stdin); freopen("money.out","w",stdout);
cin >> q;
while(q--)
{ cin >> a >> b >> c >> d >> x; right::solve(); }
return 0;
};
}
signed main()
{ return OMA::main(); }
T2
BM,多项式。
T3
分类讨论,数位dp。
T4
密码学(?)。