【bsgs】hdu4887
来源:互联网 发布:python课程推荐 编辑:程序博客网 时间:2024/06/09 14:37
可以看出这些操作是可以用一些异或实现,而异或又是满足结合律的,因此可以写成矩阵的形式
那么题目的实质就是求A^K*X=Y
就是经典的离散对数
可以写成A^(K1*SQRT(N)-K2)*X=Y -> A^(K1*sqrt(n))*X=A^K2*Y
左右两边都是sqrt(n)级别的问题,左边枚举,右边用个hash存一下答案
在算右边的答案的时候可以直接用位运算,左边的初始矩阵可以用快速幂求。
#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#include <map>#include <cmath>using namespace std;struct matrix{ int p[33][33]; int n,m; matrix () {} matrix (int N,int M) { n=N,m=M; memset(p,0,sizeof(p)); } matrix (unsigned int t,int N,int M) { n=N,m=M; memset(p,0,sizeof(p)); for (int i=n;i>=2;i--,t>>=1) p[i][1]=(t&1); p[1][1]=1; } matrix operator *(matrix &a) { matrix tmp(n,a.m); for (int i=1;i<=n;i++) for (int j=1;j<=a.m;j++) for (int k=1;k<=m;k++) tmp.p[i][j]^=(p[i][k]*a.p[k][j]); return tmp; } unsigned int size() { unsigned int ans=0; for (int i=2;i<=n;i++) ans=(ans<<1)+p[i][1]; return ans; } void print() { cout<<n<<' '<<m<<endl; for (int i=1;i<=n;i++) { for (int j=1;j<=m;j++) cout<<p[i][j]<<' '; cout<<endl; } }}A,B;int n,S1,S2;int a[50],b[50],x[50],y[50];unsigned int X,Y,lim,ans,A1,B1;map < unsigned int , int > Map;void origin(){A1=0,B1=0; A=matrix(n+1,n+1); A.p[1][1]=1; for (int i=1;i<=n-1;i++) A.p[i+1][i+2]=1; for (int i=1;i<=S1;i++) A.p[n+1][a[i]+1]=1,A1|=(1LL<<(n-a[i])); B=matrix(n+1,n+1); B.p[1][1]=1; for (int i=1;i<=n;i++) B.p[i+1][i+1]=1; for (int i=1;i<=S2;i++) B.p[b[i]+1][1]=1,B1|=(1LL<<(n-b[i])); A=B*A; X=0; for (int i=1;i<=n;i++) X=(X<<1)+x[i]; Y=0; for (int i=1;i<=n;i++) Y=(Y<<1)+y[i];}void baby(){ Map.clear(); Map[Y]=0; unsigned int X=Y; unsigned int mo=(1LL<<n)-1; for (int i=1;i<=lim;i++) { unsigned int y=((((long long)X)<<1)&(mo)); for (int j=1;j<=S1;j++) if ((X>>(n-a[j]))&1) y^=1; y^=B1; X=y; Map[y]=i; }}matrix fgm(matrix b,int e){matrix sum(b.n,b.m);for (int i=1;i<=sum.n;i++) sum.p[i][i]=1;for (;e;e>>=1) {if (e&1) sum=sum*b;b=b*b;}return sum;}int gaint(){ matrix tmp=matrix(X,n+1,1); A=fgm(A,(lim+1)); B=A; for (int i=1;(lim+1)*i-lim<=(1LL<<n);i++) { matrix tt=B*tmp; unsigned int y=tt.size(); if (Map.count(y)) { ans=(lim+1)*i-Map[y]; return 1; } B=A*B; } return 0;}int main(){freopen("input.txt","r",stdin); for (;scanf("%d%d%d",&n,&S1,&S2)==3;) { for (int i=1;i<=S1;i++) scanf("%d",&a[i]); for (int i=1;i<=S2;i++) scanf("%d",&b[i]); for (int i=1;i<=n;i++) scanf("%d",&x[i]); for (int i=1;i<=n;i++) scanf("%d",&y[i]); origin(); if (X==Y) { printf("0\n"); continue; } lim=(int)sqrt((double)(1LL<<n))+1; baby(); ans=0; if (gaint()) cout<<ans<<endl; else printf("poor sisyphus\n"); } return 0;}
0 0
- 【bsgs】hdu4887
- BSGS
- BSGS及扩展BSGS
- BSGS&扩展BSGS
- BZOJ2242【BSGS】
- bsgs算法
- bzoj3122(bsgs)
- 【Bsgs】【ExBsgs】
- bsgs算法
- 模板 BSGS
- [ BSGS ] BZOJ3239
- [ BSGS ] BZOJ2242
- [Baby steps giant steps] BSGS EXT-BSGS
- POJ3243 EXT-BSGS算法
- hash + bsgs模板
- 【bzoj3239】Discrete Logging BSGS
- bzoj3122 随机数生成器 BSGS
- BSGS算法 学习笔记
- HLS入门收集(1)
- Linux 下编译安装 PHP 5.5
- discuz入门小结
- 给一个整数数组,有正有负。找出数组最大和,条件是使用的元素不能有相邻
- C++中namespace的使用
- 【bsgs】hdu4887
- linux下安装eclipse
- js控制图片缩放、水平和垂直方向居中对齐
- ACdream-1056 Bad Horse
- C# .Net练习代码 Employee Class
- 【1】The connection to adb is down, and a severe error has occured(Android模拟器端口被占用)
- 南阳 223 小明的烦恼
- 【血泪史】Spark:一个高效的分布式计算系统
- JSONHelper