您的位置:首页 > 其它

SSL 1127 方程的解数

2018-03-07 20:54 239 查看

题目



分析

首先数据点很小,所以就用深搜,

k1x1p1+k2x2p2+……+k5x5p5+k6x6p6=0k1x1p1+k2x2p2+……+k5x5p5+k6x6p6=0

k1x1p1+k2x2p2+k3x3p3=−k4x4p4−k5x5p5−k6x6p6k1x1p1+k2x2p2+k3x3p3=−k4x4p4−k5x5p5−k6x6p6

用两个深搜

求出答案后哈希。

哈希代码

#include <cstdio>
#define mod 2600137
using namespace std;
int n,m,k[7],p[7],hash[mod+1],sum[mod+1],answer;
int pows(int x,int y){//快速幂
int ans=1;
while (y){
if (y&1) ans*=x;
x*=x; y>>=1;
}
return ans;
}
int abs(int x){return (x>0)?x:-x;}
int locate(int x){
int orig=abs(x)%mod,i=0;
while (i<mod&&hash[(orig+i)%mod]&&hash[(orig+i)%mod]!=x) i++;
return (orig+i)%mod;
}
void insert(int x){
int pos=locate(x);
hash[pos]=x;
sum[pos]++;
}
void dfs1(int dep,int s){
if (dep>n/2) insert(s);//插入
else for (int i=1;i<=m;i++) dfs1(dep+1,s+k[dep]*pows(i,p[dep]));
}
void dfs2(int dep,int s){
if (dep>n) {
int pos=locate(-s);
if (hash[pos]==-s) answer+=sum[pos];//答案
}
else for (int i=1;i<=m;i++) dfs2(dep+1,s+k[dep]*pows(i,p[dep]));
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d%d",&k[i],&p[i]);
dfs1(1,0); dfs2(n/2+1,0);
printf("%d",answer);
return 0;
}


当然快排+二分和双指针也会会给出来的

二分代码

#include <cstdio>
#include <algorithm>
using namespace std;
int n,m,k[7],p[7],a[3500001],n1,answer;
int pows(int x,int y){
int ans=1;
while (y){
if (y&1) ans*=x;
x*=x; y>>=1;
}
return ans;
}
int erfen(int l,int r,int x){
int mid;
while (l<=r){
mid=(l+r)>>1;
if (a[mid]>x) r=mid-1;
else if (a[mid]<x) l=mid+1;
else break;
}
if (a[mid]!=x) return 0;
int head=mid,tail=mid;
while (a[head]==x) head--; head++;//左右扩散
while (a[tail]==x) tail++; tail--;
return tail-head+1;
}
void dfs1(int dep,int s){
if (dep>n/2) a[++n1]=s;
else for (int i=1;i<=m;i++) dfs1(dep+1,s+k[dep]*pows(i,p[dep]));
}
void dfs2(int dep,int s){
if (dep>n) answer+=erfen(1,n1,-s);
else for (int i=1;i<=m;i++) dfs2(dep+1,s+k[dep]*pows(i,p[dep]));
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d%d",&k[i],&p[i]);
dfs1(1,0); stable_sort(a+1,a+1+n1); //快排
dfs2((n>>1)+1,0);
printf("%d",answer);
return 0;
}


双指针

#include <cstdio>
#include <algorithm>
#define check1 if (head1>n1) break//越界
#define check2 if (head2>n2) break//越界
using namespace std;
int n,m,k[7],p[7],a[3500001],b[3500001],n1,n2,answer,big,sma=2147483647;
int pows(int x,int y){
int ans=1;
while (y){
if (y&1) ans*=x;
x*=x; y>>=1;
}
return ans;
}
void dfs1(int dep,int s){
if (dep>n/2) {a[++n1]=s; big=max(big,s); sma=min(sma,s);}
else for (int i=1;i<=m;i++) dfs1(dep+1,s+k[dep]*pows(i,p[dep]));
}
void dfs2(int dep,int s){
if (dep>n) {if (big>=-s&&sma<=-s) b[++n2]=-s;}
else for (int i=1;i<=m;i++) dfs2(dep+1,s+k[dep]*pows(i,p[dep]));
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d%d",&k[i],&p[i]);
dfs1(1,0); dfs2(n/2+1,0);
stable_sort(a+1,a+1+n1); stable_sort(b+1,b+1+n2);
int head1=1,head2=1;
while (true){
int s=0;
while (a[head1]<b[head2]) head1++; check1;//前面比后面小
while (a[head1]>b[head2]) head2++; check2;//前面比后面大
while (a[head1]==b[head2]) s++,head2++; head2--;//寻找区间
while (a[head1]==b[head2]) head1++,answer+=s; check1; head2++; check2;//答案
}
printf("%d",answer);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: