比赛入口
D Almost All Divisors
做法:找出一个数字,这个数字除了1和本身的所有约数都被给出,若这些给出的数字没办法找到这样一个数字就输出-1。就是给出数字的最小值和最大值相乘,在判断这个答案是否正确…
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int N = 304;
int a[N], aa[N];
int main() {
int t; read(t);
int n;
while(t--) {
read(n);
int m = 1e6+6, M = -1;
for(int i = 0; i < n; ++i) {
read(a[i]);
m = min(m, a[i]); M = max(M, a[i]);
}
LL res = 1ll * m * M;
int k = 0;
LL j;
for(j = 2; j*j < res; ++j) {
if(res % j == 0) {
aa[k++] = j; aa[k++] = res / j;
}
}
if(j*j == res) aa[k++] = j;
if(k != n) puts("-1");
else {
int f = 1;
sort(a, a+n);
sort(aa, aa+n);
for(int i = 0; i < n; ++i) {
if(a[i] != aa[i]) {
f = 0; break;
}
}
if(!f) puts("-1");
else printf("%lld\n", res);
}
}
return 0;
}
E Two Arrays and Sum of Functions
做法:答案是每个最小的和最大的相乘再乘以出现的次数i*(n-i+1),要注意溢出的问题以及之前不能取模。
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int N = 2e5+10;
const LL Mod = 998244353;
LL a[N], b[N];
int main() {
LL n; read(n);
for(int i = 1; i <= n; ++i) {
read(a[i]);
a[i] = a[i] * i * (n - i + 1);
}
for(int i = 1; i <= n; ++i) read(b[i]);
sort(a+1, a+n+1); sort(b+1, b+n+1);
LL ans = 0;
for(int i = 1; i <= n; ++i) {
ans = (ans + (a[i] % Mod) * (b[n-i+1] % Mod) % Mod) % Mod;
}
cout << ans << endl;
return 0;
}
F Microtransactions
做法:二分答案,再检测答案是否正确。关键是检验答案是否正确的贪心写法,要选取优先选取最后一次打折,并且要注意打折了钱也不够的情况。
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int N = 2e5+5;
struct xx {
int d, t;
//按日期从大到小排序
bool operator < (const xx &c) const {
return d > c.d;
}
}b[N];
int n, m, cnt;
int a[N], c[N];
int check(int mid) {
memcpy(c, a, sizeof a);
int day = mid, now = mid, tot = cnt, x;
for(int i = 1; i <= m; ++i) {
if(b[i].d <= mid) {
now = min(now, b[i].d);
x = min(now, c[b[i].t]);
c[b[i].t] -= x;
day -= x; tot -= x; now -= x;
}
}
return day >= tot*2;
}
int main() {
read(n); read(m);
for(int i = 1; i <= n; ++i) read(a[i]), cnt += a[i];
for(int i = 1; i <= m; ++i) read(b[i].d), read(b[i].t);
sort(b+1, b+m+1);
int l = 0, r = 2*cnt;
while(l < r) {
int mid = l + r >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
cout << l << endl;
return 0;
}