刷题记录-P2312 解方程
2017-09-18 00:42
183 查看
题目链接:https://www.luogu.org/problem/show?pid=2312
这题一开始是这么考虑的:如果f(x)!=0,那么f(x)%k一定也不等于0
这样可以进行检验,选取若干个k使得解的范围缩小,
最后用高精度一一进行验证。
70分
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#define MAXN 105
#define SIZE 10025
#define MAXM 1000005
#define ll long long
using namespace std;
struct BigInt{
int len;
int s[SIZE];
int p; //p==1 + p==-1 -
BigInt(){
p=1;len=0;
memset(s,0,sizeof(s));
}
BigInt operator = (const char A[]){
int L=strlen(A);
len=L;
if('-'==A[0]){
p=-1; len--;
}
else{
p=1;
}
memset(s,0,sizeof(s));
for(int i=1;i<=len;i++){
s[i]=A[L-i]-'0';
}
return *this;
}
BigInt operator = (const BigInt &A){
len=A.len;
p=A.p;
memset(s,0,sizeof(s));
for(int i=1;i<=len;i++){
s[i]=A.s[i];
}
return *this;
}
BigInt operator *= (const int &A){
for(int i=1;i<=len;i++){
s[i]*=A;
}
for(int i=1;i<=len;i++){
s[i+1]+=s[i]/10; //+= not +
s[i]%=10;
}
int t=len;
while(s[t+1]){
t++;
s[t+1]+=s[t]/10;
s[t]%=10;
}
len=t;
return *this;
}
// compare Abs
bool operator < (const BigInt &A){
if(len!=A.len){
return (len<A.len);
}
for(int i=len;i>=1;i--){
if(s[i]!=A.s[i]){
return (s[i]<A.s[i]);
}
}
return 0;
}
BigInt operator -= (const BigInt &A){
BigInt B,C;
B=*this; C=*this;
if(B<A){
B.p=A.p;
B=A;
}
else{
B.p=p;
C=A;
}
for(int i=1;i<=C.len;i++){
B.s[i]-=C.s[i];
}
for(int i=1;i<=C.len;i++){
if(B.s[i]<0){
B.s[i]+=10;
B.s[i+1]-=1;
}
}
int t=C.len;
while(B.s[t+1]<0){
t++;
B.s[t]+=10;
B.s[t+1]-=1;
}
for(int i=B.len;i>=1;i--){
if(!B.s[i]){
B.len--;
}
else{
break;
}
}
if(!B.len) B.len=1;
return (*this=B);
}
BigInt operator += (const BigInt &A){
if(p*A.p<0){
return (*this-=A);
}
len=max(len,A.len);
for(int i=1;i<=len;i++){
s[i]+=A.s[i];
}
for(int i=1;i<=len;i++){
s[i+1]+=s[i]/10;
s[i]%=10;
}
if(s[len+1]){
len++;
s[len+1]=s[len]/10;
s[len]%=10;
}
return *this;
}
int operator % (const int &A){
int q=0;
for(int i=len;i>=1;i--){
q=q*10+s[i];
q=q%A;
}
return q*p;
}
void Print(){
if(p<0) printf("-");
for(int i=len;i>=1;i--){
printf("%d",s[i]);
}
printf("\n");
}
};
BigInt a[MAXN];
int prime[6]={0,1000193,1000367,1000427,1000453};
int n,m;
int b[MAXM];
int B[MAXN];
vector<int> ans,bans;
void read(int k){
char s[SIZE]={0};
int len=0;
char c=getchar();
do{
s[len++]=c;
c=getchar();
}while('0'<=c&&c<='9');
a[k]=s;
}
bool check(int k){
BigInt sum;
for(int i=n;i>=0;i--){
sum*=k;
sum+=a[i];
}
if(1==sum.len&&!sum.s[1]){
return 1;
}
return 0;
}
int main()
{
// freopen("T1.in","r",stdin);
// freopen("my.out","w",stdout);
scanf("%d%d",&n,&m);
getchar();
for(int i=0;i<=n;i++){
read(i);
}
for(int k=1;k<=4;k++){
for(int i=0;i<=n;i++){
B[i]=a[i]%prime[k];
}
for(int x=1;x<=m;x++){
ll sum=0;
for(int i=n;i>=0;i--){
sum=((sum*x)+B[i])%(ll)prime[k];
}
if(sum){
b[x]=-1;
}
else if(b[x]!=-1){
b[x]=1;
}
}
}
for(int i=1;i<=m;i++){
if(1==b[i]){
bans.push_back(i);
}
}
for(int i=0;i<bans.size();i++){
if(check(bans[i])){
ans.push_back(bans[i]);
}
}
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++){
printf("%d\n",ans[i]);
}
return 0;
}这题AC解法是利用类似线性筛数的思想,
如果f(x)!=0那么f(x+kMOD)!=0(这个和我的想法是一致的)
关键就在于,我们可以利用这条性质,只处理0~MOD-1的部分
然后对于x,直接对MOD取模,然后就很大程度上减少了计算量
这题一开始是这么考虑的:如果f(x)!=0,那么f(x)%k一定也不等于0
这样可以进行检验,选取若干个k使得解的范围缩小,
最后用高精度一一进行验证。
70分
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#define MAXN 105
#define SIZE 10025
#define MAXM 1000005
#define ll long long
using namespace std;
struct BigInt{
int len;
int s[SIZE];
int p; //p==1 + p==-1 -
BigInt(){
p=1;len=0;
memset(s,0,sizeof(s));
}
BigInt operator = (const char A[]){
int L=strlen(A);
len=L;
if('-'==A[0]){
p=-1; len--;
}
else{
p=1;
}
memset(s,0,sizeof(s));
for(int i=1;i<=len;i++){
s[i]=A[L-i]-'0';
}
return *this;
}
BigInt operator = (const BigInt &A){
len=A.len;
p=A.p;
memset(s,0,sizeof(s));
for(int i=1;i<=len;i++){
s[i]=A.s[i];
}
return *this;
}
BigInt operator *= (const int &A){
for(int i=1;i<=len;i++){
s[i]*=A;
}
for(int i=1;i<=len;i++){
s[i+1]+=s[i]/10; //+= not +
s[i]%=10;
}
int t=len;
while(s[t+1]){
t++;
s[t+1]+=s[t]/10;
s[t]%=10;
}
len=t;
return *this;
}
// compare Abs
bool operator < (const BigInt &A){
if(len!=A.len){
return (len<A.len);
}
for(int i=len;i>=1;i--){
if(s[i]!=A.s[i]){
return (s[i]<A.s[i]);
}
}
return 0;
}
BigInt operator -= (const BigInt &A){
BigInt B,C;
B=*this; C=*this;
if(B<A){
B.p=A.p;
B=A;
}
else{
B.p=p;
C=A;
}
for(int i=1;i<=C.len;i++){
B.s[i]-=C.s[i];
}
for(int i=1;i<=C.len;i++){
if(B.s[i]<0){
B.s[i]+=10;
B.s[i+1]-=1;
}
}
int t=C.len;
while(B.s[t+1]<0){
t++;
B.s[t]+=10;
B.s[t+1]-=1;
}
for(int i=B.len;i>=1;i--){
if(!B.s[i]){
B.len--;
}
else{
break;
}
}
if(!B.len) B.len=1;
return (*this=B);
}
BigInt operator += (const BigInt &A){
if(p*A.p<0){
return (*this-=A);
}
len=max(len,A.len);
for(int i=1;i<=len;i++){
s[i]+=A.s[i];
}
for(int i=1;i<=len;i++){
s[i+1]+=s[i]/10;
s[i]%=10;
}
if(s[len+1]){
len++;
s[len+1]=s[len]/10;
s[len]%=10;
}
return *this;
}
int operator % (const int &A){
int q=0;
for(int i=len;i>=1;i--){
q=q*10+s[i];
q=q%A;
}
return q*p;
}
void Print(){
if(p<0) printf("-");
for(int i=len;i>=1;i--){
printf("%d",s[i]);
}
printf("\n");
}
};
BigInt a[MAXN];
int prime[6]={0,1000193,1000367,1000427,1000453};
int n,m;
int b[MAXM];
int B[MAXN];
vector<int> ans,bans;
void read(int k){
char s[SIZE]={0};
int len=0;
char c=getchar();
do{
s[len++]=c;
c=getchar();
}while('0'<=c&&c<='9');
a[k]=s;
}
bool check(int k){
BigInt sum;
for(int i=n;i>=0;i--){
sum*=k;
sum+=a[i];
}
if(1==sum.len&&!sum.s[1]){
return 1;
}
return 0;
}
int main()
{
// freopen("T1.in","r",stdin);
// freopen("my.out","w",stdout);
scanf("%d%d",&n,&m);
getchar();
for(int i=0;i<=n;i++){
read(i);
}
for(int k=1;k<=4;k++){
for(int i=0;i<=n;i++){
B[i]=a[i]%prime[k];
}
for(int x=1;x<=m;x++){
ll sum=0;
for(int i=n;i>=0;i--){
sum=((sum*x)+B[i])%(ll)prime[k];
}
if(sum){
b[x]=-1;
}
else if(b[x]!=-1){
b[x]=1;
}
}
}
for(int i=1;i<=m;i++){
if(1==b[i]){
bans.push_back(i);
}
}
for(int i=0;i<bans.size();i++){
if(check(bans[i])){
ans.push_back(bans[i]);
}
}
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++){
printf("%d\n",ans[i]);
}
return 0;
}这题AC解法是利用类似线性筛数的思想,
如果f(x)!=0那么f(x+kMOD)!=0(这个和我的想法是一致的)
关键就在于,我们可以利用这条性质,只处理0~MOD-1的部分
然后对于x,直接对MOD取模,然后就很大程度上减少了计算量
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<vector> #define MAXN 105 #define SIZE 10025 #define MAXM 1000005 #define ll long long using namespace std; const int prime[]={10007,10917,30071}; int n,m; int a[MAXN][4]; bool f[MAXM][4]; char s[SIZE]; vector<int> ans; bool calc(int x,int j){ ll sum=0; for(int i=n;i>=0;i--){ sum=(sum*x+a[i][j])%prime[j]; } return (0==sum); } int main() { // freopen("T1.in","r",stdin); // freopen("my.out","w",stdout); scanf("%d%d",&n,&m); for(int i=0;i<=n;i++){ memset(s,0,sizeof(s)); scanf("%s",s); int len=strlen(s),be=0; int p=1; if('-'==s[0]){ p=-1; be++; } for(int j=0;j<3;j++){ ll temp=0; for(int k=be;k<len;k++){ temp=((temp*10)+s[k]-'0')%prime[j]; } a[i][j]=temp*p; if(a[i][j]<0) a[i][j]+=prime[j]; } } for(int j=0;j<3;j++){ for(int i=0;i<prime[j];i++){ f[i][j]=calc(i,j); } } for(int i=1;i<=m;i++){ int ok=1; for(int j=0;j<3;j++){ if(!f[i%prime[j]][j]){ ok=0; break; } } if(ok){ ans.push_back(i); } } printf("%d\n",ans.size()); for(int i=0;i<ans.size();i++){ printf("%d\n",ans[i]); } return 0; }
相关文章推荐
- 洛谷 P2312 解方程
- codevs3732==洛谷 解方程P2312 解方程
- P2312 解方程
- 洛谷 P2312 解方程
- 洛谷P2312:解方程 (Hash+数学)
- 洛谷 P2312 解方程
- 解方程正整数解 x^n+y^n=z^n 每天 看代码写代码之水题记录(1.8)费马大定理
- 【蓝桥杯学习记录】【6】不定方程的解法
- 数学——洛谷 P2312 解方程
- 洛谷 P2312 解方程
- 洛谷 P2312 解方程
- 洛谷 P2312 [NOIP2014 D2T3] 解方程
- 2017.4.25 解方程 思考记录
- STM32笔记记录2
- android 报错记录
- 【版本控制管理】SVN常见难点记录
- cocos2dx打包异常处理记录
- ACM_编程与调试重点记录(十一)
- 关于C\C++运行时库的多线程版本的工作记录
- zookeeper学习记录-02一致性协议