2019 ACM - ICPC 全国邀请赛(西安)题解(9 / 13)
Posted 繁凡さん
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019 ACM - ICPC 全国邀请赛(西安)题解(9 / 13)相关的知识,希望对你有一定的参考价值。
The 2019 ACM-ICPC China Shannxi Provincial Programming Contest
目录
VP地址:https://www.jisuanke.com/contest/21482/rank?page=1
A. Tasks
Solution
直接贪心即可。
Code
#include <bits/stdc++.h>
using namespace std;
int a[105];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i = 0;i < n;++i){
scanf("%d",&a[i]);
}
sort(a,a+n);
int cnt = 0;
for(int i = 0;i < n;++i){
if(m >= a[i]){
cnt++;
m -= a[i];
}
}
printf("%d\\n",cnt);
return 0;
}
B. Product
Solution
直接推柿子,然后杜教筛即可。
Code
#include <bits/stdc++.h>
using namespace std;
const int N = 2587401;
typedef long long ll;
#define int long long
#define mult(x, y) (1ll * x * y >= mod ? 1ll * x * y % mod : 1ll * x * y)
#define minus(x, y) (1ll * x - y < 0 ? 1ll * x - y + mod : 1ll * x - y)
#define plus(x, y) (1ll * x + y >= mod ? 1ll * x + y - mod : 1ll * x + y)
#define ck(x) (x >= mod : x - mod : x)
ll n, m, p, mod;
ll primes[N], cnt;
bool vis[N];
ll d[N], num[N];
ll phi[N];
unordered_map<ll, ll> sum_phi;
unordered_map<ll, ll> sum_xdx;
ll qpow(ll a, ll b, ll mod)
{
ll res = 1;
while(b) {
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
void init(ll n)
{
d[1] = 1;
vis[0] = vis[1] = 1;
phi[1] = 1;
for(int i = 2; i <= n; ++ i) {
if(vis[i] == 0) {
primes[ ++ cnt] = i;
phi[i] = i - 1;
d[i] = 2, num[i] = 1;
}
for(int j = 1; j <= cnt && i * primes[j] <= n; ++ j) {
vis[i * primes[j]] = 1;
if(i % primes[j] == 0) {
phi[i * primes[j]] = phi[i] * primes[j];
num[i * primes[j]] = num[i] + 1;
d[i * primes[j]] = d[i] / num[i * primes[j]] * (num[i * primes[j]] + 1) % mod;
break;
}
phi[i * primes[j]] = phi[i] * phi[primes[j]];
num[i * primes[j]] = 1;
d[i * primes[j]] = (d[i] * 2) % mod;
}
}
for(int i = 1; i <= n; ++ i) {
phi[i] = plus(phi[i], phi[i - 1]);
d[i] = 1ll * d[i] * i % mod;
d[i] = plus(1ll * d[i], d[i - 1]);
}
}
inline int g_sum(ll x)
{
return x;
}
inline ll get_sum_phi(ll x)
{
if(x <= N - 7) return phi[x];
if(sum_phi.find(x) != sum_phi.end()) return sum_phi[x];
ll ans = 1ll * x * (1ll * x + 1) / 2;
for(ll l = 2, r; l <= x;l = r + 1) {
r = x / (x / l);
ans -= 1ll * (g_sum(r) - g_sum(l - 1)) * get_sum_phi(x / l);
}
return sum_phi[x] = ans / g_sum(1);
}
inline ll get_sum_xdx(ll x)
{
if(x <= N - 7) return d[x];
if(sum_xdx.find(x) != sum_xdx.end()) return sum_xdx[x];
ll ans = 0;
for(ll l = 1, r; l <= x; l = r + 1) {
r = x / (x / l);
ans = (ans + 1ll * ((1ll * x / l + 1) * (1ll * x / l) / 2) % mod * ((1ll * r - l + 1) * (l + r) / 2) % mod) % mod;
}
return sum_xdx[x] = ans;
}
ll solve()
{
ll res = 0;
for(ll l = 1, r; l <= n; l = r + 1) {
r = n / (n / l);
res = (res + (get_sum_xdx(r) - get_sum_xdx(l - 1) + mod) % mod * get_sum_phi(n / l)) % mod;
}
res = plus(res, res) % mod;
//res = minus(res, get_sum_xdx(n));
// cout << get_sum_xdx(n) << endl;
//cout << (res - get_sum_xdx(n) + mod) % mod << endl;
//res = res - get_sum_xdx(n);
return (res - get_sum_xdx(n) + mod) % mod;
}
signed main()
{
scanf("%lld%lld%lld", &n, &m, &p);
mod = p - 1;
init(N - 7);
ll b = solve();
printf("%lld\\n", qpow(m, b, p));
return 0;
}
C. Angel’s Journey
Solution
实际上就是求点到圆上一点的最短距离。判断一下,求切线然后计算距离即可。
Code
#include <bits/stdc++.h>
#define LL long long
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define PI 3.1415926535897932384626
#define EXIT exit(0);
#define DEBUG puts("Here is a BUG");
#define CLEAR(name, init) memset(name, init, sizeof(name))
const double eps = 1e-6;
const int MAXN = (int)1e9 + 5;
using namespace std;
#define Vector Point
#define ChongHe 0
#define NeiHan 1
#define NeiQie 2
#define INTERSECTING 3
#define WaiQie 4
#define XiangLi 5
int dcmp(double x) { return fabs(x) < eps ? 0 : (x < 0 ? -1 : 1); }
struct Point {
double x, y;
Point(const Point& rhs): x(rhs.x), y(rhs.y) { } //拷贝构造函数
Point(double x = 0.0, double y = 0.0): x(x), y(y) { } //构造函数
friend istream& operator >> (istream& in, Point& P) { return in >> P.x >> P.y; }
friend ostream& operator << (ostream& out, const Point& P) { return out << P.x << ' ' << P.y; }
friend Vector operator + (const Vector& A, const Vector& B) { return Vector(A.x+B.x, A.y+B.y); }
friend Vector operator - (const Point& A, const Point& B) { return Vector(A.x-B.x, A.y-B.y); }
friend Vector operator * (const Vector& A, const double& p) { return Vector(A.x*p, A.y*p); }
friend Vector operator / (const Vector& A, const double& p) { return Vector(A.x/p, A.y/p); }
friend bool operator == (const Point& A, const Point& B) { return dcmp(A.x-B.x) == 0 && dcmp(A.y-B.y) == 0; }
friend bool operator < (const Point& A, const Point& B) { return A.x < B.x || (A.x == B.x && A.y < B.y); }
void in(void) { scanf("%lf%lf", &x, &y); }
void out(void) { printf("%lf %lf", x, y); }
};
struct Line {
Point P; //直线上一点
Vector dir; //方向向量(半平面交中该向量左侧表示相应的半平面)
double ang; //极角,即从x正半轴旋转到向量dir所需要的角(弧度)
Line() { } //构造函数
Line(const Line& L): P(L.P), dir(L.dir), ang(L.ang) { }
Line(const Point& P, const Vector& dir): P(P), dir(dir) { ang = atan2(dir.y, dir.x); }
bool operator < (const Line& L) const { //极角排序
return ang < L.ang;
}
Point point(double t) { return P + dir*t; }
};
typedef vector<Point> Polygon;
struct Circle {
Point c; //圆心
double r; //半径
Circle() { }
Circle(const Circle& rhs): c(rhs.c), r(rhs.r) { }
Circle(const Point& c, const double& r): c(c), r(r) { }
Point point(double ang) const { return Point(c.x + cos(ang)*r, c.y + sin(ang)*r); } //圆心角所对应的点
double area(void) const { return PI * r * r; }
};
double Dot(const Vector& A, const Vector& B) { return A.x*B.x + A.y*B.y; } //点积
double Length(const Vector& A){ return sqrt(Dot(A, A)); } //向量长度
double Angle(const Vector& A, const Vector& B) { return acos(DotACM-ICPC 2018全国邀请赛(陕西西安)
2019 ACM - ICPC 全国邀请赛(南昌) 题解(9 / 12)
The 2019 ACM-ICPC China Shannxi Provincial Programming Contest (西安邀请赛重现) J. And And And
2021 ICPC全国邀请赛(西安)太原理工大学收获3枚奖牌