Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
Re:终于过了,有几点要说的In Reply To:终于过了,有几点要说的 Posted by:jiyanmoyu at 2010-02-25 13:41:29 > 一是题目求的是 x^y%z == k%z,最小的非负整数y > 二是不用解线性方程的办法是将对数离散成如此形式: x^(i*m) = k*(x^j),用数组存所有的 > k*(x^j)即可,注意m=(int)ceil((double)z)+1; i从 1枚举到m,如果有答案,就是i*m-j; > 三是数组快速排序与二分查找时有一个地方要注意,就是有些不同的j,(k*(x^j))%z的值是相同的,这时,对于相同的k*(x^j)%z,j的顺序也要注意,不然可能二分出的不是最小的值。在快速排序时要注意不同的j值,但在查找时与j值却无关。 > 附上自己的代码:(只能用g++交) > #include<iostream> > #include<algorithm> > using namespace std; > #include<cmath> > #include<fstream> > typedef long long lld; > struct hash > { > lld j,xj; > bool operator<(const hash &other)const > { > if(xj==other.xj) > return j>other.j; > return xj<other.xj; > } > }; > hash table[100000]; > inline bool cmp2(const hash &h1,const hash &h2) > { > return h1.xj<h2.xj; > } > lld exp_mod(lld a,lld b,lld n)// a^b%n > { > lld res=1%n; > while(b>0) > { > if(b&0x01) > res=res*a%n; > a=a*a%n; > b>>=1; > } > return res; > } > int main() > { > lld x,z,k; > while(cin>>x>>z>>k&&!(0==x&&0==z&&0==k)) > { > x=x%z; > k=k%z; > lld m=(lld)ceil(sqrt((double)z))+1; > lld xj=k%z; > lld j; > for(j=0;j<m;++j) > { > table[j].j=j; > table[j].xj=xj; > xj=xj*x%z; > } > sort(table,table+m); > lld xm=exp_mod(x,m,z); > lld i; > lld left=1%z; > bool getAns=false; > for(i=1;i<=m;++i) > { > left=left*xm%z; > hash *p=lower_bound(table,table+m,(hash){0,left},cmp2); > if(p!=table+m&&(*p).xj==left) > { > j=(*p).j; > getAns=true; > break; > } > } > if(getAns) > cout<<i*m-j<<endl; > else > cout<<"No Solution"<<endl; > } > return 0; > } > Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator