8.3 2020牛客暑期多校训练营(第八场)题解及补题
8.3 2020牛客暑期多校训练营(第八场)题解及补题
比赛过程
爆零场,实在是不应该,最起码应该签到,组内这场的分配策略需要进一步调整。
题解
E Enigmatic Partition
题意
数\(n\)的拆分,需要满足最大和最小差2,相邻两个数的差值不能超过1.
\(f(n)\)表示这种拆分的个数。给定\(l\),\(r\), 求区间和。
\(T ≤ 10000 1 ≤ l ≤ r ≤ 100000\)
解法
因为每个数字是由三个连续数字构成,然后数目不确定,所以我们枚举第一个数字\(l\),那么就知道这三个数字是\(l\),\(l+1\),\(l+2\)。
我们枚举l的数目和\(l+1\)的数目,或者枚举\(l+1\)和\(l+2\)的数目。
因为两个\(l+1\)可以变成一个\(l\)和一个\(l+2\),所以只要枚举两个就可以了。
然后又\(x\)个\(l\),\(y\)个\(l+1\)的时候,就能得到\((y-1)/2\)个变换情况。
\(x\)个\(l+2\),\(y\)个\(l+1\)同理。
但是小数据的时候很慢,直接跑完全背包就好了。
代码
#pragma region
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, n) for (int i = a; i <= n; ++i)
#define per(i, a, n) for (int i = n; i >= a; --i)
namespace fastIO {
#define BUF_SIZE 100000
#define OUT_SIZE 100000
//fread->R
bool IOerror = 0;
//inline char nc(){char ch=getchar();if(ch==-1)IOerror=1;return ch;}
inline char nc() {
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if (p1 == pend) {
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if (pend == p1) {
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch) { return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'; }
template <class T>
inline bool R(T &x) {
bool sign = 0;
char ch = nc();
x = 0;
for (; blank(ch); ch = nc())
;
if (IOerror) return false;
if (ch == '-') sign = 1, ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc()) x = x * 10 + ch - '0';
if (sign) x = -x;
return true;
}
inline bool R(double &x) {
bool sign = 0;
char ch = nc();
x = 0;
for (; blank(ch); ch = nc())
;
if (IOerror) return false;
if (ch == '-') sign = 1, ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc()) x = x * 10 + ch - '0';
if (ch == '.') {
double tmp = 1;
ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc())
tmp /= 10.0, x += tmp * (ch - '0');
}
if (sign)
x = -x;
return true;
}
inline bool R(char *s) {
char ch = nc();
for (; blank(ch); ch = nc())
;
if (IOerror)
return false;
for (; !blank(ch) && !IOerror; ch = nc())
*s++ = ch;
*s = 0;
return true;
}
inline bool R(char &c) {
c = nc();
if (IOerror) {
c = -1;
return false;
}
return true;
}
template <class T, class... U>
bool R(T &h, U &... t) { return R(h) && R(t...); }
#undef OUT_SIZE
#undef BUF_SIZE
}; // namespace fastIO
using namespace fastIO;
template <class T>
void _W(const T &x) { cout << x; }
void _W(const int &x) { printf("%d", x); }
void _W(const int64_t &x) { printf("%lld", x); }
void _W(const double &x) { printf("%.16f", x); }
void _W(const char &x) { putchar(x); }
void _W(const char *x) { printf("%s", x); }
template <class T, class U>
void _W(const pair<T, U> &x) { _W(x.fa), putchar(' '), _W(x.S); }
template <class T>
void _W(const vector<T> &x) {
for (auto i = x.begin(); i != x.end(); _W(*i++))
if (i != x.cbegin()) putchar(' ');
}
void W() {}
template <class T, class... U>
void W(const T &head, const U &... tail) { _W(head), putchar(sizeof...(tail) ? ' ' : '\n'), W(tail...); }
#pragma endregion
const int maxn = 1e5 + 500;
const int mod=1e9+7;
ll gcd(ll T, ll b) { return b == 0 ? T : gcd(b, T % b); }
ll lcm(ll T, ll b) { return T / gcd(T, b) * b; }
ll mul(ll a,ll b, ll c) {
ll ans = 0;
while(b) {
if(b&1) {
ans= (ans+a)%c;
b--;
}
b>>=1;
a=(a+a)%c;
}
return ans;
}
ll powmod(ll a,ll b,ll c) {
ll ans = 1;
while(b) {
if(b&1) {
ans = mul(ans,a,c);
b--;
}
b>>=1;
a=mul(a,a,c);
}
return ans ;
}
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
ll sum[maxn];
ll dp[55][maxn];
void init() {
for(int l = 50;l < maxn;l++) {
int mid = l + 1;
int r = l + 2;
for(int nl = 1;nl * l < maxn;nl++) {
for(int m = 3;m * mid + l * nl < maxn;m++) {
sum[m * mid + l * nl] += (m - 1) / 2;
}
}
for(int nr = 0;nr * r < maxn;nr++) {
for(int m = 3;m * mid + r * nr < maxn;m++) {
sum[m * mid + r * nr] += (m - 1) / 2;
}
}
}
for(int l = 1;l < 50;l++) {
int a[10];
a[1] = l;a[2] = l + 1;a[3] = l + 2;
int num = a[1] + a[2] + a[3];
dp[l][0] = 1;
for(int i = 1;i <= 3;i++) {
for(int j = a[i];j < maxn;j++) {
dp[l][j] += dp[l][j - a[i]];
}
}
for(int j = num;j < maxn;j++) {
sum[j] += dp[l][j - num];
}
}
for(int i = 1;i < maxn;i++) {
sum[i] += sum[i - 1];
}
}
int main() {
init();
int T;
scanf("%d",&T);
int iCase = 0;
while(T--) {
int l,r;
scanf("%d%d",&l,&r);
printf("Case #%d: %lld\n",++iCase,sum[r] - sum[l - 1]);
}
return 0;
}
G Game SET
题意
每个卡牌有4个属性,每个属性有4个值,一个值是通配符,可以改成任意一个值。
求三张卡牌,使得对任意一个属性,要么全相同,要么全不同。
解法
找到解(21个),所以暴力就好了
代码
#pragma region
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, n) for (int i = a; i <= n; ++i)
#define per(i, a, n) for (int i = n; i >= a; --i)
namespace fastIO {
#define BUF_SIZE 100000
#define OUT_SIZE 100000
//fread->R
bool IOerror = 0;
//inline char nc(){char ch=getchar();if(ch==-1)IOerror=1;return ch;}
inline char nc() {
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if (p1 == pend) {
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if (pend == p1) {
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch) { return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'; }
template <class T>
inline bool R(T &x) {
bool sign = 0;
char ch = nc();
x = 0;
for (; blank(ch); ch = nc())
;
if (IOerror) return false;
if (ch == '-') sign = 1, ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc()) x = x * 10 + ch - '0';
if (sign) x = -x;
return true;
}
inline bool R(double &x) {
bool sign = 0;
char ch = nc();
x = 0;
for (; blank(ch); ch = nc())
;
if (IOerror) return false;
if (ch == '-') sign = 1, ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc()) x = x * 10 + ch - '0';
if (ch == '.') {
double tmp = 1;
ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc())
tmp /= 10.0, x += tmp * (ch - '0');
}
if (sign)
x = -x;
return true;
}
inline bool R(char *s) {
char ch = nc();
for (; blank(ch); ch = nc())
;
if (IOerror)
return false;
for (; !blank(ch) && !IOerror; ch = nc())
*s++ = ch;
*s = 0;
return true;
}
inline bool R(char &c) {
c = nc();
if (IOerror) {
c = -1;
return false;
}
return true;
}
template <class T, class... U>
bool R(T &h, U &... t) { return R(h) && R(t...); }
#undef OUT_SIZE
#undef BUF_SIZE
}; // namespace fastIO
using namespace fastIO;
template <class T>
void _W(const T &x) { cout << x; }
void _W(const int &x) { printf("%d", x); }
void _W(const int64_t &x) { printf("%lld", x); }
void _W(const double &x) { printf("%.16f", x); }
void _W(const char &x) { putchar(x); }
void _W(const char *x) { printf("%s", x); }
template <class T, class U>
void _W(const pair<T, U> &x) { _W(x.fa), putchar(' '), _W(x.S); }
template <class T>
void _W(const vector<T> &x) {
for (auto i = x.begin(); i != x.end(); _W(*i++))
if (i != x.cbegin()) putchar(' ');
}
void W() {}
template <class T, class... U>
void W(const T &head, const U &... tail) { _W(head), putchar(sizeof...(tail) ? ' ' : '\n'), W(tail...); }
#pragma endregion
const int maxn = 1e5 + 500;
const int mod=1e9+7;
ll gcd(ll T, ll b) { return b == 0 ? T : gcd(b, T % b); }
ll lcm(ll T, ll b) { return T / gcd(T, b) * b; }
ll mul(ll a,ll b, ll c) {
ll ans = 0;
while(b) {
if(b&1) {
ans= (ans+a)%c;
b--;
}
b>>=1;
a=(a+a)%c;
}
return ans;
}
ll powmod(ll a,ll b,ll c) {
ll ans = 1;
while(b) {
if(b&1) {
ans = mul(ans,a,c);
b--;
}
b>>=1;
a=mul(a,a,c);
}
return ans ;
}
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
map<string,int>MP;
unordered_map<int,int>mp;
int a[maxn][10];
void init() {
MP["one"] = 1;MP["two"] = 2;MP["three"] = 3;
MP["diamond"] = 1;MP["squiggle"] = 2;MP["oval"] = 3;
MP["solid"] = 1;MP["striped"] = 2;MP["open"] = 3;
MP["red"] = 1;MP["green"] = 2;MP["purple"] = 3;
MP["*"] = 0;
}
int P[10] = {1,4,16,64,256};
bool check(int *a,int *b,int *c) {
for(int i = 0;i < 4;i++) {
int x = a[i],y = b[i],z = c[i];
if(x == y && y == z) continue;
else if(x != y && y != z && x != z) continue;
else if(x == 0 || y == 0 || z == 0) continue;
else return false;
}
return true;
}
int dfs(vector<int>num[4],int a,int b) {
for(int i = 0;i < num[0].size();i++) {
for(int j = 0;j < num[1].size();j++) {
for(int k = 0;k < num[2].size();k++) {
for(int q = 0;q < num[3].size();q++) {
int x = num[0][i] * 4 * 4 * 4 + num[1][j] * 4 * 4 + num[2][k] * 4 + num[3][q];
if(mp[x] && mp[x] != a && mp[x] != b) return mp[x];
}
}
}
}
return -1;
}
int main() {
init();
srand(time(NULL));
int T;scanf("%d",&T);
int kase = 0;
while(T--) {
int n;scanf("%d",&n);
mp.clear();
for(int i = 1;i <= n;i++) {
string str;cin >> str;
int pre = 0;
int num[10];
int cnt = 0;
for(int j = 0;j < str.size();j++) {
if(str[j] == '[') pre = j;
else if(str[j] == ']') {
int len = j - pre - 1;
string now = str.substr(pre + 1,len);
num[cnt] = MP[now];
cnt++;
}
}
for(int j = 0;j < 4;j++) {
a[i][j] = num[j];
}
int Num = num[0] * 4 * 4 * 4 + num[1] * 4 * 4 + num[2] * 4 + num[3];
mp[Num] = i;
}
printf("Case #%d: ",++kase);
int flag = 0;
for(int i = 1;i <= n;i++) {
for(int j = i + 1;j <= n;j++) {
vector<int>num[4];
for(int k = 0;k < 4;k++) {
if(a[i][k] == 0 || a[j][k] == 0) {
for(int q = 0;q < 4;q++) {
num[k].push_back(q);
}
} else if(a[i][k] == a[j][k]) {
num[k].push_back(a[i][k]);
num[k].push_back(0);
} else if(a[i][k] != a[j][k]) {
for(int q = 0;q < 4;q++) {
if(q == a[i][k] || q == a[j][k]) continue;
num[k].push_back(q);
}
} else {
break;
}
}
int x = dfs(num,i,j);
if(x != -1 && check(a[i],a[j],a[x])) {
printf("%d %d %d\n",i,j,x);
flag = 1;
break;
}
}
if(flag) break;
}
if(!flag) printf("-1\n");
}
return 0;
}
I Interesting Computer Game
题意
给了两个数组:\({a_1,a_2,\cdots,a_n}\),\({b_1,b_2,\cdots,b_n}\),\(n≤10^5\)。
第\(i\)步可以从\(a_i\)和\(b_i\)中选择一个数。
求最后选出的数中,不同的数要最多。
解法
既然是两个数组,可以二元组\((a_i,b_i)\)当成一条边,用总点数减减(k个点,k-1条边的连通分量)
代码
#pragma region
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, n) for (int i = a; i <= n; ++i)
#define per(i, a, n) for (int i = n; i >= a; --i)
namespace fastIO {
#define BUF_SIZE 100000
#define OUT_SIZE 100000
//fread->R
bool IOerror = 0;
//inline char nc(){char ch=getchar();if(ch==-1)IOerror=1;return ch;}
inline char nc() {
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if (p1 == pend) {
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if (pend == p1) {
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch) { return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'; }
template <class T>
inline bool R(T &x) {
bool sign = 0;
char ch = nc();
x = 0;
for (; blank(ch); ch = nc())
;
if (IOerror) return false;
if (ch == '-') sign = 1, ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc()) x = x * 10 + ch - '0';
if (sign) x = -x;
return true;
}
inline bool R(double &x) {
bool sign = 0;
char ch = nc();
x = 0;
for (; blank(ch); ch = nc())
;
if (IOerror) return false;
if (ch == '-') sign = 1, ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc()) x = x * 10 + ch - '0';
if (ch == '.') {
double tmp = 1;
ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc())
tmp /= 10.0, x += tmp * (ch - '0');
}
if (sign)
x = -x;
return true;
}
inline bool R(char *s) {
char ch = nc();
for (; blank(ch); ch = nc())
;
if (IOerror)
return false;
for (; !blank(ch) && !IOerror; ch = nc())
*s++ = ch;
*s = 0;
return true;
}
inline bool R(char &c) {
c = nc();
if (IOerror) {
c = -1;
return false;
}
return true;
}
template <class T, class... U>
bool R(T &h, U &... t) { return R(h) && R(t...); }
#undef OUT_SIZE
#undef BUF_SIZE
}; // namespace fastIO
using namespace fastIO;
template <class T>
void _W(const T &x) { cout << x; }
void _W(const int &x) { printf("%d", x); }
void _W(const int64_t &x) { printf("%lld", x); }
void _W(const double &x) { printf("%.16f", x); }
void _W(const char &x) { putchar(x); }
void _W(const char *x) { printf("%s", x); }
template <class T, class U>
void _W(const pair<T, U> &x) { _W(x.fa), putchar(' '), _W(x.S); }
template <class T>
void _W(const vector<T> &x) {
for (auto i = x.begin(); i != x.end(); _W(*i++))
if (i != x.cbegin()) putchar(' ');
}
void W() {}
template <class T, class... U>
void W(const T &head, const U &... tail) { _W(head), putchar(sizeof...(tail) ? ' ' : '\n'), W(tail...); }
#pragma endregion
const int maxn = 1e5 + 500;
const int mod=1e9+7;
ll gcd(ll T, ll b) { return b == 0 ? T : gcd(b, T % b); }
ll lcm(ll T, ll b) { return T / gcd(T, b) * b; }
ll mul(ll a,ll b, ll c) {
ll ans = 0;
while(b) {
if(b&1) {
ans= (ans+a)%c;
b--;
}
b>>=1;
a=(a+a)%c;
}
return ans;
}
ll powmod(ll a,ll b,ll c) {
ll ans = 1;
while(b) {
if(b&1) {
ans = mul(ans,a,c);
b--;
}
b>>=1;
a=mul(a,a,c);
}
return ans ;
}
int fa[maxn*2];
void init() {
memset(fa, -1, sizeof(fa));
}
int a[maxn], b[maxn];
int c[maxn*2];
int find(int x) {
if (fa[x] == -1) return x;
return fa[x] = find(fa[x]);
}
bool vis[maxn*2];
void join(int x, int y) {
int t1 = find(x);
int t2 = find(y);
if (t1 == t2) {
vis[t1] = true;
return;
}
fa[t1] = t2;
if (vis[t1]) vis[t2] = true;
}
int main() {
int T;
scanf("%d", &T);
int iCase = 0;
while (T--) {
init();
memset(vis, false, sizeof(vis));
int n;
scanf("%d", &n);
int tot = 0;
for (int i = 0; i < n; i++) {
scanf("%d%d", &a[i], &b[i]);
c[tot++] = a[i];
c[tot++] = b[i];
}
sort(c, c+tot);
tot = unique(c, c+tot) - c;
for (int i = 0; i < n; i++) {
int x = lower_bound(c, c+tot, a[i]) - c;
int y = lower_bound(c, c+tot, b[i]) - c;
join(x, y);
}
int ans = tot;
for (int i = 0; i < tot; i++)
if (fa[i] == -1 && !vis[i])//有连通分量ans--
ans--;
printf("Case #%d: %d\n", ++iCase, ans);
}
return 0;
}
K Kabaleo Lite
题意
有n种菜,每种菜的数量为 \(b_i\) , 每个菜的盈利为 \(a_i\).
每个顾客必须从第1种菜开始,连续地吃,每种吃一个。
保证顾客最多的情况下,盈利最大
解法
\(b_1\)就是最大顾客数量。然后求盈利的前缀和,从大到小取即可。结果会超出long long。
复杂度$O(n) $或者 \(O(nlogn)\)都可以。
代码
#pragma region
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#include <bits/stdc++.h>
using namespace std;
//typedef long long ll;
typedef __int128 ll;
#define rep(i, a, n) for (int i = a; i <= n; ++i)
#define per(i, a, n) for (int i = n; i >= a; --i)
namespace fastIO {
#define BUF_SIZE 100000
#define OUT_SIZE 100000
//fread->R
bool IOerror = 0;
//inline char nc(){char ch=getchar();if(ch==-1)IOerror=1;return ch;}
inline char nc() {
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if (p1 == pend) {
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if (pend == p1) {
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch) { return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'; }
template <class T>
inline bool R(T &x) {
bool sign = 0;
char ch = nc();
x = 0;
for (; blank(ch); ch = nc())
;
if (IOerror) return false;
if (ch == '-') sign = 1, ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc()) x = x * 10 + ch - '0';
if (sign) x = -x;
return true;
}
inline bool R(double &x) {
bool sign = 0;
char ch = nc();
x = 0;
for (; blank(ch); ch = nc())
;
if (IOerror) return false;
if (ch == '-') sign = 1, ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc()) x = x * 10 + ch - '0';
if (ch == '.') {
double tmp = 1;
ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc())
tmp /= 10.0, x += tmp * (ch - '0');
}
if (sign)
x = -x;
return true;
}
inline bool R(char *s) {
char ch = nc();
for (; blank(ch); ch = nc())
;
if (IOerror)
return false;
for (; !blank(ch) && !IOerror; ch = nc())
*s++ = ch;
*s = 0;
return true;
}
inline bool R(char &c) {
c = nc();
if (IOerror) {
c = -1;
return false;
}
return true;
}
template <class T, class... U>
bool R(T &h, U &... t) { return R(h) && R(t...); }
#undef OUT_SIZE
#undef BUF_SIZE
}; // namespace fastIO
using namespace fastIO;
template <class T>
void _W(const T &x) { cout << x; }
void _W(const int &x) { printf("%d", x); }
void _W(const int64_t &x) { printf("%lld", x); }
void _W(const double &x) { printf("%.16f", x); }
void _W(const char &x) { putchar(x); }
void _W(const char *x) { printf("%s", x); }
template <class T, class U>
void _W(const pair<T, U> &x) { _W(x.fa), putchar(' '), _W(x.S); }
template <class T>
void _W(const vector<T> &x) {
for (auto i = x.begin(); i != x.end(); _W(*i++))
if (i != x.cbegin()) putchar(' ');
}
void W() {}
template <class T, class... U>
void W(const T &head, const U &... tail) { _W(head), putchar(sizeof...(tail) ? ' ' : '\n'), W(tail...); }
#pragma endregion
const int maxn = 1e5 + 500;
const int mod=1e9+7;
ll gcd(ll T, ll b) { return b == 0 ? T : gcd(b, T % b); }
ll lcm(ll T, ll b) { return T / gcd(T, b) * b; }
ll mul(ll a,ll b, ll c) {
ll ans = 0;
while(b) {
if(b&1) {
ans= (ans+a)%c;
b--;
}
b>>=1;
a=(a+a)%c;
}
return ans;
}
ll powmod(ll a,ll b,ll c) {
ll ans = 1;
while(b) {
if(b&1) {
ans = mul(ans,a,c);
b--;
}
b>>=1;
a=mul(a,a,c);
}
return ans ;
}
const ll N = 1e5 + 5;
ll a[N],b[N];
ll dp[N];//前缀和
ll n,t;
#define P pair<ll, pair<ll, ll>> //第一个存dp[i], 第二个存数量, 第三个存菜的下标(第几道菜)
priority_queue <P> que;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(ll x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
ll solve() {
ll res = 0;
ll pos_now = n, now_food_num = 0;
while (!que.empty()) {
ll max_price = que.top().first; //最大利润
ll food_num = que.top().second.first; //菜品数量
ll pos = que.top().second.second; //菜品名
que.pop();
if (pos_now <= pos || food_num <= now_food_num) { //当该菜品位置位于pos_now之后则不可上菜
continue;
}
res += (food_num - now_food_num) * max_price; //(需要减去上次用的菜品,因为其数量的价值上一次已经算过了)
now_food_num = food_num; //更新上一次用去的菜品数量
pos_now = pos; //更新菜品位置
}
return res;
}
int main() {
t = read();
for(ll i = 1; i <= t; i++) {
n = read();
for(ll j = 0; j < n; j++) {
a[j] = read();
if (!j) dp[j] = a[j];
else dp[j] = dp[j-1] + a[j];
}
for(ll j = 0; j < n; j++) {
b[j] = read();
}
ll bb = b[0];
for (ll j = 0; j < n; j++) {
bb = min(bb, b[j]);
que.push({dp[j], {bb, j}});
}
ll ans = solve();
cout << "Case #";
print(i);
cout << ": ";
print(b[0]);
cout << " ";
print(ans);
puts("");
}
return 0;
}

浙公网安备 33010602011771号