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;
}

posted @ 2020-08-16 21:48  cugbacm03  阅读(142)  评论(0)    收藏  举报