开局20分钟就开始罚坐的经典场又来了qaq
A. Red and Blue Beans
使用
m
i
n
(
r
,
b
)
min(r,b)
min(r,b)个packet来装
r
i
r_i
ri和
b
i
b_i
bi,要使得
∣
r
i
−
b
i
∣
≤
d
|r_i-b_i|\leq d
∣ri−bi∣≤d,则必有使
m
a
x
(
r
,
b
)
max(r,b)
max(r,b)尽可能均分装入
m
i
n
(
r
,
b
)
min(r,b)
min(r,b)个packet里面。判断均分后
r
i
r_i
ri和
b
i
b_i
bi的最大差值是否小于等于d即可。
即判断
⌈
m
a
x
(
r
,
b
)
m
i
n
(
r
,
b
)
⌉
\lceil \frac{max(r,b)}{min(r,b)}\rceil
⌈min(r,b)max(r,b)⌉是否
≤
d
\leq d
≤d即可。
void solves(){
int r,b;cin>>r>>b;
if(r<b) swap(r,b);
int n=r/b-1+(r%b!=0);
int d;cin>>d;
if(n<=d)cout<<"YES\n";
else cout<<"NO\n";
}
B. The Cake Is a Lie
从(1,1)走到(n,m),只能向下或者向右走,即一定向右走了m-1步,向下走了n-1步。不管怎么走,最后的总权值都是不变的,只是将权值进行拆分重新求和。说的有点抽象,随便感觉一下吧,我也不知道怎么证明。
任选一条路,易推的最后权值n-1+n*(m-1),化简得n*m-1。
void solves(){
int n,m,k;cin>>n>>m>>k;
if(k==n*m-1)cout<<"YES\n";
else cout<<"NO\n";
}
C. Berland Regional
第一眼只想到了o(n* n * nlogn)的sb写法,感觉铁t,然后就溜了…确实应该认真再想想的qaq。
模拟即可,set+前缀和优化一下。
bool cmp(pair<int,int>a,pair<int,int>b){
return a.second>b.second;
}
void solves(){
int n;cin>>n;
vector<pair<int,int>>a(n+7);
vector<vector<ll>>re(n+7);
set<ll>st;
for(int i=0;i<n;++i){
cin>>a[i].first;
st.insert(a[i].first);
}
for(int i=0;i<n;++i) cin>>a[i].second;
sort(a.begin(),a.end(),cmp);
vector<ll>ans(n+7);
for(int i=0;i<n;++i)re[a[i].first].push_back(a[i].second);
for(auto it:st){
int len=re[it].size();
vector<ll>qian(len+7);
qian[0]=re[it][0];
for(int i=1;i<len;++i) qian[i]=qian[i-1]+re[it][i];
for(int i=1;i<=len;++i){
ans[i]+=qian[len-1-len%i];
}
}
for(int i=1;i<=n;++i) cout<<ans[i]<<" ";cout<<endl;
}
D. Maximum Sum of Products
第一眼看见这题只会reverse,感觉铁t,读完题就果断溜了。
先处理一下
a
i
∗
b
i
a_i*b_i
ai∗bi的前缀。然后通过枚举反转区间的中点来枚举所有情况,显然,奇数区间和偶数区间的枚举方法是不一样的。
const int N=5e3+7;
ll a[N],b[N],qian[N];
ll ans=0;
int n;
void ji(int x){
ll res=a[x]*b[x];
ans=max(ans,res+qian[n]-qian[x]+qian[x-1]);
for(int l=x-1,r=x+1;l>=1&&r<=n;--l,++r){
res+=a[r]*b[l]+a[l]*b[r];
ans=max(ans,res+qian[n]-qian[r]+qian[l-1]);
}
}
void ou(int x){
ll res=a[x+1]*b[x]+a[x]*b[x+1];
ans=max(ans,res+qian[n]-qian[x+1]+qian[x-1]);
for(int l=x-1,r=x+2;l>=1&&r<=n;--l,++r){
res+=a[r]*b[l]+a[l]*b[r];
ans=max(ans,res+qian[n]-qian[r]+qian[l-1]);
}
}
void solves(){
cin>>n;
for(int i=1;i<=n;++i) cin>>a[i];
for(int i=1;i<=n;++i){
cin>>b[i];
qian[i]=qian[i-1]+a[i]*b[i];
}
for(int i=1;i<=n;++i) ji(i);
for(int i=1;i<n;++i) ou(i);
cout<<ans<<endl;
}