QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#767797 | #9738. Make It Divisible | i_wish_a_girl_friend# | WA | 1ms | 9800kb | C++23 | 4.3kb | 2024-11-20 22:12:22 | 2024-11-20 22:12:27 |
Judging History
answer
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
//const int mod=998244353;
int gcd(int a,int b){return b?gcd(b,a%b):a;};
int qpw(int a,int b,int mod){int ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
//int inv(int x){return qpw(x,mod-2);}
const int MAX_N = 5e4+10;
const int LOG = 17; // log2(MAX_N) 的上界
int rs_min[MAX_N],ls_min[MAX_N],root_min;
int n, a[MAX_N];
int up[MAX_N][LOG]; // 倍增表:up[i][k] 表示从 i 向上跳 2^k 步后的节点
int gcd_table[MAX_N][LOG]; // gcd_table[i][k] 表示从 i 到 up[i][k] 的 GCD 值
int parent[MAX_N]; // 笛卡尔树中的父节点
int depth[MAX_N]; // 每个节点的深度
int query_min(int l,int r){
int x=root_min;
for(;;x=(r<x?ls_min[x]:rs_min[x]))if(l<=x&&x<=r)return x;
}
// 构建笛卡尔树,并初始化倍增表
void build_cartesian_tree() {
vector<int> stack;
for (int i = 1; i <= n; i++) {
int last = 0;
while (!stack.empty() && a[stack.back()] > a[i]) {
last = stack.back();
stack.pop_back();
}
if (!stack.empty()) {
parent[i] = stack.back();
up[i][0] = stack.back();
gcd_table[i][0] = gcd(a[i], a[stack.back()]);
} else {
parent[i] = 0;
up[i][0] = 0;
gcd_table[i][0] = a[i];
}
if (last) {
parent[last] = i;
up[last][0] = i;
gcd_table[last][0] = gcd(a[last], a[i]);
}
stack.push_back(i);
}
}
// 倍增预处理
void preprocess() {
for (int k = 1; (1 << k) <= n; k++) {
for (int i = 1; i <= n; i++) {
if (up[i][k - 1]) {
up[i][k] = up[up[i][k - 1]][k - 1];
gcd_table[i][k] = gcd(gcd_table[i][k - 1], gcd_table[up[i][k - 1]][k - 1]);
}
}
}
}
// 查询两个节点之间的 GCD
int query_gcd(int l, int r) {
int result = 0;
for (int k = LOG - 1; k >= 0; k--) {
if (up[l][k] && up[l][k] <= r) {
result = gcd(result, gcd_table[l][k]);
l = up[l][k];
}
}
return gcd(result, a[l]);
}
void solve(){
int k;cin>>n>>k;
set<int>sb;
for(int i=1,x;i<=n;i++)cin>>a[i],sb.insert(a[i]);
if(sb.size()==1){
cout<<k<<" "<<k*(k+1)/2<<'\n';
return;
}
vector<int>sta(n+1);
function<void()>build_min=[&](){
int top=0,cur=0;
for(int i=1;i<=n;i++){
cur=top;
while(cur&&a[sta[cur]]>=a[i])cur--;
if(cur)rs_min[sta[cur]]=i;
if(cur<top)ls_min[i]=sta[cur+1];
sta[++cur]=i;
top=cur;
}
};
build_min();
root_min=sta[1];
vector<int>c(n+1);
for(int i=1;i<=n;i++)c[i]=a[i];
int gc=0,mx=0;
for(int i=n;i>=2;i--)a[i]=abs(a[i]-a[i-1]),gc=gcd(gc,a[i]),mx=max(mx,a[i]);
a[1]=gc;
build_cartesian_tree();preprocess();
set<int>dp,ndp;
// cout<<query_gcd(2,n)<<'\n';
function<void(int,int)>dfs=[&](int l,int r){
if(l>=r)return;
if(l==1&&r==n){
int G=query_gcd(l+1,r);
int mid=query_min(l,r);
for(int i=1;i*i<=G;i++){
if(G%i)continue;
if(i-c[mid]>0&&i-c[mid]<=k)
dp.insert(i-c[mid]);
if(G/i-c[mid]>0&&G/i-c[mid]<=k)
dp.insert(G/i-c[mid]);
}
dfs(l,mid-1);
dfs(mid+1,r);
}
else {
ndp.clear();
int G= query_gcd(l+1,r);
int mid=query_min(l,r);
for(int i=1;i*i<=G;i++){
for(int x:dp){
if(G%(a[mid]+x))ndp.insert(x);
}
}
dfs(l,mid-1);
dfs(mid+1,r);
}
};
dfs(1,n);
int sum=0;
for(int x:dp)sum+=x;
cout<<dp.size()<<" "<<sum<<'\n';
}
signed main(){
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int _=1;
cin>>_;
while(_--)solve();
}
/*
3
5 10
7 79 1 7 1
2 1000000000
1 2
1 100
1000000000
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 9732kb
input:
3 5 10 7 79 1 7 1 2 1000000000 1 2 1 100 1000000000
output:
3 8 0 0 100 5050
result:
ok 3 lines
Test #2:
score: -100
Wrong Answer
time: 1ms
memory: 9800kb
input:
4 201 1000000000 1 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5 2 5...
output:
0 0 1 1 0 0 0 0
result:
wrong answer 2nd lines differ - expected: '0 0', found: '1 1'