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; }
相关文章推荐
- SSL-ZYC 1127 方程的解数
- ssl1127-方程的解数【HASH,dfs】
- SSL_1127 方程的解数
- SSL_1227_方程的解数_dfs_hash
- 记一次配置SSL的问题
- tomcat6 ssl+yale csa 简单配置
- SSL 2647_线段树练习四_线段树
- SSL网站的建立与访问
- Download interrupted: Connection to https://dl-ssl.google.com refused
- Linux Nginx 配置SSL访问实例详解
- SSL认证机构是干什么的,在电子商务中如何实现?
- Firefox 34:SSLv3安全漏洞修复,全新的HTML5实现
- (ssl1072、ssl1273、ssl1274)P2347 砝码称重
- Apache SSL Module 介绍,原理及安装
- Apache SSL单双向证书认证
- Apache + SSL搭建Linux证书服务器
- 利用sniffer技术捕捉SSL通信时客户端证书公钥
- 求方程的根
- SSL1585 取数游戏(递归)