CF1781 D. Many Perfect Squares [数学题]

2024-02-18 02:04

本文主要是介绍CF1781 D. Many Perfect Squares [数学题],希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

传送门:CF

[前题提要]:一道有意思的数学题


直接想这道题是不好想的(博主当时就完全没有思路).那么考虑将一个大问题分解成一个小问题想一下(感觉这种思考方式在CF题中还是挺常见的),考虑如果同时存在多个完全平方数,那么必然满足存在两个完全平方数.而当我们确定了任意两个数之后,我们就可以反推出其他数.

考虑如果存在两个数同时为完全平方数会发生什么?
a [ i ] + x = p 2 , a [ j ] + x = q 2 a[i]+x=p^2,a[j]+x=q^2 a[i]+x=p2,a[j]+x=q2 a [ j ] − a [ i ] = q 2 − p 2 = ( q + p ) ∗ ( q − p ) a[j]-a[i]=q^2-p^2=(q+p)*(q-p) a[j]a[i]=q2p2=(q+p)(qp)不难发现存在这样的一个事实,两个数的差一定可以分解为两个因子.诶,那么此时我们完全可以枚举差的因数,当我们枚举这个时,我们同时也就确定了 x x x

那么此时这道题的解法也就呼之欲出了,我们先枚举任意两个数,将其作为我们假设的完全平方数,因为假设我们同时存在更多的完全平方数,这种情况必然是包括上述我们枚举的情况的.考虑确定完两个数之后,我们就可以通过枚举因数来确定 x x x,确定完 x x x之后,我们可以将其代回去,对于我们的每一个数都加上 x x x,从而计算出此时的贡献,然后取一个 m a x max max即可.

考虑 1 e 9 1e9 1e9以内的最大因数个数很少,是 1 e 3 1e3 1e3级别的(准确来说是1344个),所以此时我们的复杂度为 1 e 3 ∗ n 3 + n 2 n 1e3*n^3+n^2\sqrt{n} 1e3n3+n2n ,差不多为 2 e 8 2e8 2e8,4s时限能够接受.


下面是具体的代码部分:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define root 1,n,1
#define ls (rt<<1)
#define rs (rt<<1|1)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {ll x=0,w=1;char ch=getchar();for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';return x*w;
}
inline void print(__int128 x){if(x<0) {putchar('-');x=-x;}if(x>9) print(x/10);putchar(x%10+'0');
}
#define maxn 1000000
#define int long long
const double eps=1e-8;
#define	int_INF 0x3f3f3f3f
#define ll_INF 0x3f3f3f3f3f3f3f3f
int a[maxn];
signed main() {int T=read();while(T--) {int n=read();for(int i=1;i<=n;i++) {a[i]=read();}int ans=1;for(int i=1;i<=n;i++) {for(int j=i+1;j<=n;j++) {vector<pair<int,int> >v; int limit=__builtin_sqrt(a[j]-a[i]);for(int k=1;k<=limit;k++) {if((a[j]-a[i])%k==0) {int num1=min(k,(a[j]-a[i])/k);int num2=max(k,(a[j]-a[i])/k);v.push_back({num1,num2});}}for(auto [x,y]:v) {int q=(x+y)/2;int p=(y-x)/2;int X=q*q-a[j];if(!(X>=0&&X<=1e18)) continue;int sum=0;for(int k=1;k<=n;k++) {if((a[k]+X)==(int)__builtin_sqrt(a[k]+X)*(int)__builtin_sqrt(a[k]+X)) {sum++;}}ans=max(ans,sum);}}}cout<<ans<<endl;}return 0;
}

这篇关于CF1781 D. Many Perfect Squares [数学题]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/719696

相关文章

洛谷 P10584 [蓝桥杯 2024 国 A] 数学题(整除分块+杜教筛)

题目 思路来源 登录 - Luogu Spilopelia 题解 参考了两篇洛谷题解,第一篇能得出这个式子,第二篇有比较严格的复杂度分析 结合去年蓝桥杯洛谷P9238,基本就能得出这题的正确做法 代码 #include<bits/stdc++.h>#include<iostream>#include<cstdio>#include<map>#include<uno

PAT甲级 1085 Perfect Sequence 二分和双指针(Two Pointers)

二分写法 #include <bits/stdc++.h>using namespace std;int find_upper_bound(const vector<long long>& nums, long long x){int beg = 0, end = nums.size(), mid = beg + (end - beg) / 2;while (beg < end) {mid

Redis Too many open files

问题 在测试并发的时候,当达到了一定值的时候,日志会显示错误: ConnectionError: Error 24 connecting CACHEREDIS-HOST:6379. Too many open files. 解决办法 查看redis的maxclients. CONFIG GET maxclients //查看同一时间最大客户端连接数 Redis的连接还受到本身系统的

mysql(mariadb)报错超过连接数: ERROR 1040 (HY000): Too many connections

在此记录下解决过程 1、vi /etc/my.cnf  [Service]新添加两行如下参数: wait_timeout = 600 interactive_timeout = 600 max_connections=4096 2、vi  usr/lib/systemd/system/mariadb.service [Service]新添加两行如下参数: LimitNOFILE=1

HDU-3038 How Many Answers Are Wrong 带权并查集

http://acm.hdu.edu.cn/showproblem.php?pid=3038 //题目大意:有n次询问,给出a到b区间的总和,问这n次给出的总和中有几次是和前面已近给出的是矛盾的??//权为i到p[i]的‘距离’#include <iostream>#include <stdio.h>#include <string.h>using namespace st

HDU-3038 How Many Answers Are Wrong

题目链接 #include <iostream>#include <stdio.h>#include <string.h>using namespace std;#define maxn 200020int n,m;int p[maxn],weight[maxn]; //并查集祖先结点 并查集权值int find(int x){if( p[x] == x ) re

hdu 1978 How many ways(记忆化搜索dp)

How many ways Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3663    Accepted Submission(s): 2135 Problem Description 这是一个简单的生存游戏

POJ 2002 Squares hash求正方形个数

题意:给你n个点 坐标都小于20000 数一下可以组成多少个正方形 思路:借鉴了网上hash的思路 哈希链地址法 把x+y的绝对值相同的放人一个链表里 然后枚举2个点(1条边上的) 推算出另外2个点 另外2点分别是 x1 = a[i].x+(a[i].y-a[j].y);y1 = a[i].y-(a[i].x-a[j].x); x2 = a[j].x+(a[i].y-a[j].y);y2

HDU 2157 How many ways?? 矩阵快速幂求A经过K个点到B方案数

题意:求A经过K个点到B方案数 1个0 1 的矩阵 A a[i][j] = 1 表示i 到 j可达 或者说 i 到 j 有1条路 或者说i到j经过一个点的方案数 路可以重复走   而A2 = A* A a[i][j] 的含义是 从i到j经过2个点的方案数 A的k次方 A[i,j]代表 i到j走k步的方案有a[i][j] T组询问 x y z 快速幂求出A矩阵的y次 然后输出A[x

ZOJ 3557 How Many Sets II lucas 定理

插空法 大组合数取余 #include <cstdio>#include <cstring>using namespace std;typedef long long LL;//求整数x和y,使得ax+by=d, 且|x|+|y|最小。其中d=gcd(a,b) void gcd(LL a, LL b, LL& d, LL& x, LL& y){if(!b){d = a;x = 1;