QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#621587 | #5301. Modulo Ruins the Legend | PonyHex | RE | 0ms | 3652kb | C++20 | 3.5kb | 2024-10-08 15:33:21 | 2024-10-08 15:33:23 |
Judging History
answer
#define _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define double long double
//#define int long long
#define lc u<<1
#define rc u<<1|1
#define endl "\n"
#define X first
#define Y second
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> PII;
const ll N = 1e5 + 5;
const ll maxm = 2e18;
//const ll mod = 1e9 + 7;
ll exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1; y = 0;
return a;
}
ll g = exgcd(b, a % b, x, y);
ll temp = x;
x = y;
y = temp - (a / b) * y;
return g;
}
ll gcd(ll a, ll b) {
return b ? gcd(b, a % b) : a;
}
//ll A[N];
void solve() {
/*
ll n,mod; cin >> n >> mod;
//ll a, b, k, x, y; scanf("%lld%lld%lld", &a, &b, &k);
ll a = n % mod, b = n * (n + 1) / 2 % mod;
ll sum = 0;
for (int i = 1; i <= n; i++)cin >> A[i], sum += A[i];
ll x, y;
ll d = exgcd(a, b, x, y);
x = x * 1 / d;
y = (1 - a * x) / b;
cout << gcd(a, b) << endl;*/
//刚才推的有问题,ans应该为:sum+k*gcd(gcd(a,b),m);,a=n,b=n*(n+1)/2;
ll n, mod; cin >> n >> mod; ll sum = 0;
for (int i = 1; i <= n; i++) {
ll val; cin >> val, sum += val; sum %= mod;
}
ll a = n%mod, b = n * (n + 1) / 2%mod;
/*
for (int i = 1; i <= 10; i++) {
cout << (sum + i * gcd(gcd(a, b), mod)) % mod << endl;
}*/
//原式为:k2*gcd(a,b)+k1*m=sum+k3*gcd(gcd(a,b),m)
//=k4gcd(gcd(a,b),m),因为结果为任意一个,所以不妨直接取
//感觉还是有问题,再推一个来
//推到的式子是ans=k3*(gcd(gcd(a,b),m))+sum
//可以看做是1*ans-k3*(gcd(gcd(a,b),m))=sum
//不对,这样求出的是任意的ans,不是最小的ans
///现在的问题是是要找到(sum+x*(gcd(gcd(a,b),m)))%mod的最小值
//应该能出了
//都快出了,思路又偏,ans=k3*(gcd(gcd(a,b),m))+sum
//最小的ans应该为sum%(gcd(gcd(a,b),m))
ll base = gcd(gcd(a, b), mod)%mod;
ll ans = sum % mod; ans %= base;
/*
if (base % mod == 0||ans==0){}
else {
//ll dis = mod - base;
//ll cnt = dis / base;
//if (dis % base != 0)cnt++;
//ll ex = cnt * base - mod;//这是在ans上一直放base
ll k = (ans + mod - 1) / mod; // 向上取整
ll min_value = (ans + k * mod - ans) % mod;
ans = min_value;
}*/
//cout << ans << " " << base << endl;
cout << ans << endl;
//然后剩下就简单了
//最后就是a*x+b*y+sum=ans-k1*mod
//只要满足ans-sum-k1*mod=k2*gcd(a,b)即可
//所以,ans-sum=k1*mod+k2*gcd(a,b)
//好像也没有很简单,利用ans-sum=k1*mod+k2*gcd(a,b)解出k2
//后面写的不好,
ll x, y; exgcd(a, b, x, y);//然后看ans-sum-k1*mod是gcd(a,b)的几倍
x %= mod; y %= mod;
//cout << x << " " << y << endl;
//ans已知,sum已知,此时ans-sum-k1*mod=k2*gcd(a,b)
//也就是视为,k1*mod+k2*gcd(a,b)=ans-sum;
//先算出k2,然后看看ans-sum是gcd(mod,gcd(a,b))的多少倍,
ll k1, k2; exgcd(mod, gcd(a, b), k1, k2);
//cout << k1 << " " << k2 << endl;
k2 *= (ans - sum) / gcd(mod, gcd(a, b)); k2 %= mod;
//cout << k2 << endl;
/*
x *= k2; x %= mod;
y *= k2; y %= mod;*/
x = (x * k2 % mod + mod) % mod;
y = (y * k2 % mod + mod) % mod;
cout << x << " " << y << endl;
return;
}
signed main() {
IOS;
ll t = 1;
//cin >> t;
while (t--) {
solve();
}
return 0;
}
/*
ll ksm(ll a, ll b) {
ll base = a;
ll ans = 1;
while (b) {
if (b & 1)ans *= base;
base *= base;
b >>= 1;
}
return ans;
}*/
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3580kb
input:
6 24 1 1 4 5 1 4
output:
1 15 19
result:
ok ok
Test #2:
score: 0
Accepted
time: 0ms
memory: 3652kb
input:
7 29 1 9 1 9 8 1 0
output:
0 0 0
result:
ok ok
Test #3:
score: -100
Runtime Error
input:
1 1 0