2023杭电第四场补题报告 1003 1006 1007 1010 1012
1003 Simple Set Problem (hdu.edu.cn)
思路
双指针直接暴力扫过去,复杂度O(n),但是卡常数,换了超级快读才ac。
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve();
#define re register
inline char nc() {
static char buf[100000], *p1 = buf, *p2 = buf;
// static 个人理解为只作用于设定地点的变量,每次返回时数组不变
//例如:退出函数时,数组存放了1,再次进入函数,数组依然存放着1,所以这句话也可以写成全局变量
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
? EOF
: *p1++;
// fread(buf,1,100000,stdin)
// 读入100000次,长度为1,存入buf中,fread返回值为有效读取字符数
// p1=读入文件头,p2=读入文件尾,如果p1==p2,证明读完文件
// buf数组清空时才会继续读入
//可运用C++的调试查看具体过程
}
//类模板
//可随读入类型的不同,自动变化类型
// fread快读=正常的快读 把getchar改成自定义的读入
template <class T>
inline void read(T &x) {
x = 0;
char c = nc();
bool p = false;
for (; '0' > c || c > '9'; c = nc()) p |= c == '-';
for (; '0' <= c && c <= '9'; c = nc()) x = (x << 1) + (x << 3) + (c ^ 48);
x = p ? -x : x;
}
void write(int x) {
if (x < 0) putchar('-'), x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
return;
}
signed main() {
// cin.sync_with_stdio(0);
// cin.tie(0);
int T;
read(T);
// cin >> T;
while (T--) {
solve();
}
return 0;
}
#define N 4000100
vector<int> g[N];
void solve() {
int k;
read(k);
vector<int> a;
// cin >> k;
for (int i = 0; i < k; i++) {
g[i].clear();
int c;
read(c);
// cin >> c;
for (int j = 0; j < c; j++) {
int x;
read(x);
// cin >> x;
g[i].push_back(x);
}
sort(g[i].begin(), g[i].end());
unique(g[i].begin(), g[i].end());
for (int z : g[i]) a.push_back(z);
}
sort(a.begin(), a.end());
unique(a.begin(), a.end());
vector<pair<int, vector<int>>> v(a.size());
for (int i = 0; i < a.size(); i++) {
v[i].first = a[i];
}
for (int i = 0; i < k; i++) {
for (int z : g[i]) {
int id = lower_bound(a.begin(), a.end(), z) - a.begin();
v[id].second.push_back(i);
}
}
int l = 0, r = 0;
vector<int> cnt(k);
int tc = 0;
int ans = 0x3f3f3f3f3f3f3f3f;
for (; r < v.size();) {
while (r < v.size() && tc < k) {
for (auto z : v[r].second) {
if (cnt[z] == 0) {
tc++;
}
cnt[z]++;
}
r++;
}
while (l < r && tc == k) {
ans = min(ans, abs(v[r - 1].first - v[l].first));
for (auto z : v[l].second) {
cnt[z]--;
if (cnt[z] == 0) {
tc--;
}
ans = min(ans, abs(v[r - 1].first - v[l].first));
}
l++;
}
}
write(ans);
putchar('\n');
}
1006 PSO (hdu.edu.cn)
思路
直接推公式,签到。
代码
#include <bits/stdc++.h>
#define int long long
#define LL long long
#define endl '\n'
#define P pair<int,int>
#define FOR(i,n) for(int i = 1;i <= n;i ++)
using namespace std;
const int N = 2e5 + 10;
const int mod = 1e9 + 7;
int n,m,k,x,y,a[N],b[N];
void solve() {
cin >> n;
if(n != 2)
printf("%.9lf %.9lf\n",(double)(n-1)/n*2,(double)2);
else {
printf("%.9lf %.9lf\n",(double)(n-1)/n*2,(double)1);
}
}
signed main() {
ios_base::sync_with_stdio(0),cin.tie(0);
//freopen("in.txt", "r", stdin);
int t = 1;
cin >> t;
while(t--) solve();
return 0;
}
1007 Guess (hdu.edu.cn)
思路
打表找规律,然后发现除了是某个质数的整数次幂之外都是1。需要用到大质数的质因数分解,牺牲精确度换取时间。
代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define fi first
#define sc second
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e8 + 10;
const int mod = 998244353;
typedef pair<int, int> PII;
int n, m;
int a[N];
int primes[N], cnt; // primes[]存储所有素数
bool st[N]; // st[x]存储x是否被筛掉
int tol; //质因数的个数,编号为0~tol-1
long long factor[100]; //质因素分解结果(刚返回时是无序的)
const int S = 8; //随机算法判定次数,一般8~10次就够了
#define re register
inline char nc() {
static char buf[100000], *p1 = buf, *p2 = buf;
// static 个人理解为只作用于设定地点的变量,每次返回时数组不变
//例如:退出函数时,数组存放了1,再次进入函数,数组依然存放着1,所以这句话也可以写成全局变量
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
? EOF
: *p1++;
// fread(buf,1,100000,stdin)
// 读入100000次,长度为1,存入buf中,fread返回值为有效读取字符数
// p1=读入文件头,p2=读入文件尾,如果p1==p2,证明读完文件
// buf数组清空时才会继续读入
//可运用C++的调试查看具体过程
}
//类模板
//可随读入类型的不同,自动变化类型
// fread快读=正常的快读 把getchar改成自定义的读入
template <class T>
inline void read(T &x) {
x = 0;
char c = nc();
bool p = false;
for (; '0' > c || c > '9'; c = nc()) p |= c == '-';
for (; '0' <= c && c <= '9'; c = nc()) x = (x << 1) + (x << 3) + (c ^ 48);
x = p ? -x : x;
}
void write(int x) {
if (x < 0) putchar('-'), x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
return;
}
int ksm(int a, int b, int p) {
int ret = 1;
for (; b; b >>= 1, a = (__int128)a * a % p)
if (b & 1) ret = (__int128)ret * a % p;
return ret;
}
bool Miinter_Rabin(int p) {
if (p < 2) return 0;
if (p == 2 || p == 3) return 1;
int d = p - 1, r = 0;
while (!(d & 1)) ++r, d >>= 1;
for (int k = 0; k < 10; ++k) {
int a = rand() % (p - 2) + 2;
int x = ksm(a, d, p);
if (x == 1 || x == p - 1) continue;
for (int i = 0; i < r - 1; ++i) {
x = (__int128)x * x % p;
if (x == p - 1) break;
}
if (x != p - 1) return 0;
}
return 1;
}
int Pointard_Rho(int x) {
int s = 0, t = 0;
int c = (int)rand() % (x - 1) + 1;
int step = 0, goal = 1;
int val = 1;
for (goal = 1;; goal <<= 1, s = t, val = 1) {
for (step = 1; step <= goal; step++) {
t = ((__int128)t * t + c) % x;
val = (__int128)val * abs(t - s) % x;
if (step % 127 == 0) {
int d = __gcd(val, x);
if (d > 1) return d;
}
}
int d = __gcd(val, x);
if (d > 1) return d;
}
}
void f(int x) {
if (x < 2) return;
if (Miinter_Rabin(x)) {
factor[tol++] = x;
return;
}
int p = x;
while (p == x) p = Pointard_Rho(x);
f(x / p);
f(p);
}
void solve() {
read(n);
tol = 0;
f(n);
sort(factor, factor + tol);
set<int> st;
for (int i = 0; i < tol; i++) {
// cout << factor[i] << " ";
st.insert(factor[i]);
}
if (st.size() == 1) {
cout << *st.begin() % mod << "\n";
} else
cout << 1 << "\n";
}
signed main() {
IOS;
int t = 1;
read(t);
for (int i = 1; i <= t; i++) {
solve();
}
}
1010 Kong Ming Qi (hdu.edu.cn)
思路
通过模拟小样例猜的结论,证明很复杂,和三元组和群论有关。
代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define fi first
#define sc second
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int, int> PII;
int n, m;
int a[N];
void solve() {
cin >> n >> m;
if (n == 1 || m == 1) {
cout << (n + m - 2) / 2 + 1 << "\n";
} else {
if (n % 3 == 0 || m % 3 == 0) {
cout << 2 << "\n";
} else {
cout << 1 << "\n";
}
}
}
signed main() {
IOS;
int t = 1;
cin >> t;
for (int i = 1; i <= t; i++) {
solve();
}
}
1012 a-b Problem (hdu.edu.cn)
思路
按和的大小从大到小排序,依次取即可。
代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define fi first
#define sc second
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int, int> PII;
int n;
void solve() {
cin >> n;
priority_queue<PII> s1;
vector<int> v(n + 10);
vector<PII> ss;
ss.push_back({0, 0});
for (int i = 1; i <= n; i++) {
int x, y;
cin >> x >> y;
s1.push({x + y, i});
ss.push_back({x, y});
}
int cnt = n;
int res = 0;
while (cnt--) {
if ((n - cnt) % 2) {
do {
auto tmp = s1.top();
s1.pop();
int id = tmp.sc;
if (v[id])
continue;
else {
v[id] = 1;
res += ss[id].fi;
break;
}
} while (s1.size());
} else {
do {
auto tmp = s1.top();
s1.pop();
int id = tmp.sc;
if (v[id])
continue;
else {
v[id] = 1;
res -= ss[id].sc;
break;
}
} while (s1.size());
}
}
cout << res << "\n";
}
signed main() {
IOS;
int t = 1;
cin >> t;
for (int i = 1; i <= t; i++) {
solve();
}
}