莫名又开始摸鱼了 泪目
A. Strange Partition
给定n个数字和一个整数x,你可以把其中任意连续的数换成一个他们的和,生成一个新的数列{bi},随后求
[sum_{i=1}^k leftlceil frac{b_i}{x} ight ceil ]输出其最大与最小值
。。。因为没有注意输出形式fst了。。。给我整个科学计数法海星
最小值就是所有的和向上取整,最大是每个数向上取整。
#include <iostream>
#include <cstring>
#include <stdio.h>
#include <algorithm>
#include <set>
#include<vector>
#include<cmath>
#include <map>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
ll n, t,x;
set<ll> a;
vector<ll>ans;
ll datt[500000 + 5];
int main() {
ios::sync_with_stdio(false);
cin >> t;
while (t--)
{
ll minn=0, maxnn=0;
cin >> n >> x;
for (int i = 0; i < n; i++) {
ll tmp;
cin >> tmp;
maxnn +=ceil(1.0 * tmp / x);
minn += tmp;
}
cout << ll(ceil(minn * 1.0 / x)) << ' ' << maxnn<<'
';
}
}
B. Strange List
给定一串数列和数字x,从头开始,有以下操作,如果当前指针指向的数q能够整除x,就往数列尾部加上x个q/x,然后指针后移一位。如果不能整除,操作停止,求此时数列中所有数字之和。
q,x个q/x,x平方个q/(x^2)等等的和都是q,因此循环对数组进行判断,如果能整除就直接加上q,然后数组值/=x
#include <iostream>
#include <cstring>
#include <stdio.h>
#include <algorithm>
#include <set>
#include<vector>
#include<cmath>
#include <map>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
ll n, t,x;
vector<ll>a;
ll ans;
ll datt[500000 + 5];
int main() {
ios::sync_with_stdio(false);
cin >> t;
while (t--)
{
a = vector<ll>();
ans = 0;
cin >> n >> x;
for (int i = 0; i < n; i++) {
cin >> datt[i];
ans += datt[i];
a.push_back(datt[i]);
}
ll flag = 1;
while (flag)
{
for (int i = 0; i < n; i++) {
if (a[i] % x == 0) {
a[i] /= x;
ans += datt[i];
}
else {
flag = 0;
break;
}
}
}
cout << ans << '
';
}
}
C. Strange Birthday Party
n个伙伴,每个人对应一个数字Ki,然后有m个礼物Cj,价格从1到m上升,可以直接给朋友j<=Ki的礼物或者给朋友Cki的钱,给礼物的话每种只能给一次
问如果分配花钱最少
对Ki排序,从大到小,Ki大的优先用便宜的礼物即可。
#include <iostream>
#include <cstring>
#include <stdio.h>
#include <algorithm>
#include <set>
#include<vector>
#include<cmath>
#include <map>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
ll n, m,t;
vector<ll>a;
ll ans;
ll datt[500000 + 5];
ll datt2[500000 + 5];
int main() {
ios::sync_with_stdio(false);
cin >> t;
while (t--)
{
ans = 0;
cin >> n >> m;
for (int i = 0; i < n; i++)cin >> datt[i];
for (int i = 0; i < m; i++) {
cin >> datt2[i];
}
sort(datt, datt + n);
ll j = 0;
for (ll i = n - 1; i >= 0; i--) {
if (datt[i]-1 < j)ans += datt2[datt[i]-1];
else {
ans += datt2[j];
j++;
}
}
cout << ans << '
';
}
}
D. Strange Definition
如果x和y满足 (frac{lcm(x, y)}{gcd(x, y)}) 是完全平方数,他们就相适应。给定一串数列,每秒,该数列中的数变为数列中与其适应的所有数的乘积。给定q个查询,查询当前数列中,所有相适应组中最大组的数字个数。
-
(frac{lcm(x, y)}{gcd(x, y)} = frac{xy}{gcd(x, y)^2}) 是完全平方数的充要条件是x*y是完全平方数,即x*y中每个质因子都有偶数个,我们可以记录x的所有为奇数个的质因子,与y的进行比较,若两者相同即满足条件
-
如果一组相适应的数字个数为偶数个,相乘后的数所有质因子就都是偶数了,其就可以和原本质因子都是偶数个的数成一组 。如果为奇数个即没有变化。因此只有第一次相乘能够改变结果。
-
把每个数奇数的质因子hash一下用map统计即可。
ps.每个变量都用ll居然t了,换成int就能过了
#include <iostream>
#include <cstring>
#include <stdio.h>
#include <algorithm>
#include <set>
#include<vector>
#include<cmath>
#include <map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
ll n, m, t;
ll ans;
ll dat[500000 + 5] = {};
ll mk[500000 + 5] = {};
ull hashs = 20111203;
map<ull, int> mp;
void func(int k) {
vector<int> tmp;
for (int i = 2; i * i <= k; i++) {
if (k % i == 0) {
int cnt = 0;
while (k % i == 0)
{
k /= i;
cnt++;
}
if (cnt & 1)tmp.push_back(i);
}
}
if (k > 1)tmp.push_back(k);
ull tmp2 = 0;
for (int i = 0; i < tmp.size(); i++) {
tmp2 = tmp2 * hashs + tmp[i];
}
mp[tmp2]++;
}
int main() {
ios::sync_with_stdio(false);
cin >> t;
while (t--)
{
mp = map<ull, int>();
cin >> n;
ll tmp;
for (int i = 0; i < n; i++) {
cin >> tmp;
func(tmp);
}
int ans1 = 0, ans2 = 0;
for (auto it = mp.begin(); it != mp.end(); it++) {
ans1 = max(ans1, it->second);
if (!(it->second&1) || it->first == 0)ans2 += it->second;
}
ans2 = max(ans1, ans2);
ll m;
cin >> m;
for (int i = 0; i < m; i++) {
cin >> tmp;
if (tmp > 0)cout << ans2 << '
';
else cout << ans1 << '
';
}
}
}