您的位置:首页 > 其它

扩展欧几里得--part4

2017-11-01 20:51 155 查看

题目精选

A/B

要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。

Input

数据的第一行是一个T,表示有T组数据。

每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。

Output

对应每组数据输出(A/B)%9973。

模板求b的乘法逆元

#include<bits/stdc++.h>
using namespace std;
const int mod=9973;
int x,y;
int ex_gcd(int a,int b,int &x,int &y)
{   int d=a;
if(b)
{
d=ex_gcd(b,a%b,x,y);
x-=(a/b)*y;swap(x,y);
}
else
x=1,y=0;
return d;
}
int main()
{
int t,n,b,ans;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&b);
ex_gcd(b,mod,x,y);
ans=n*x%mod;if(ans<0)ans+=mod;
printf("%d\n",ans);
}
}


xiaoxin juju needs help

As we all known, xiaoxin is a brilliant coder. He knew palindromic strings when he was only a six grade student at elementry school.

This summer he was working at Tencent as an intern. One day his leader came to ask xiaoxin for help. His leader gave him a string and he wanted xiaoxin to generate palindromic strings for him. Once xiaoxin generates a different palindromic string, his leader will give him a watermelon candy. The problem is how many candies xiaoxin’s leader needs to buy?

Input

This problem has multi test cases. First line contains a single integer T(T≤20)T(T≤20) which represents the number of test cases.

For each test case, there is a single line containing a string S(1≤length(S)≤1,000)S(1≤length(S)≤1,000).

Output

For each test case, print an integer which is the number of watermelon candies xiaoxin’s leader needs to buy after mod 1,000,000,0071,000,000,007.

先求出全排列,之后除以重复的东西(套上乘法逆元).

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=1e9+7;
ll jie(int len)
{ll ret=1;
for(int i=1;i<=len;i++)
{ret*=i;ret%=mod;}
return ret;
}
ll x,y;
int ex_gcd(ll a,ll b,ll &x,ll &y)
{   ll d=a;
if(b)
{d=ex_gcd(b,a%b,x,y);
x-=(a/b)*y;swap(x,y);x%=mod;y%=mod;}
else
x=1,y=0;
return d;
}
int main()
{
int t,flg=0,i,flag=0,len;string s;ll b,ans,tmp,mp[26];
scanf("%d",&t);
while(t--)
{   memset(mp,0,sizeof mp);flg=0;
cin>>s;flag=(s.length()&1);ans=1;b=1;
for(i=0;i<s.length();i++)
mp[s[i]-'a']++;
for(i=0;i<=25;i++)
{if(mp[i]&1)flg++;mp[i]/=2;}
if(flg>flag)
{printf("0\n");continue;}
len=s.length()/2;ans=jie(len);
for(i=0;i<=25;i++)
{if(mp[i])b*=jie(mp[i]);b%=mod;}
ex_gcd(b,mod,x,y);
ans=ans*x%mod;if(ans<0)ans+=mod;
printf("%lld\n",ans);
}
}


Solutions to an Equation

You have to find the number of solutions of the following equation:

Ax + By + C = 0

Where A, B, C, x, y are integers and x1 ≤ x ≤ x2 and y1 ≤ y ≤ y2.

Input

Input starts with an integer T (≤ 10000), denoting the number of test cases.

Each case starts with a line containing seven integers A, B, C, x1, x2, y1, y2 (x1 ≤ x2, y1 ≤ y2). The value of each integer will lie in the range [-108, 108].

Output

For each case, print the case number and the total number of solutions.

话说这题实际上不难,几乎是模板,但解不等式最好用double方便用上下取整符号,同时注意一个为0或者两个为0的情况特判.

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll x,y;
ll ex_gcd(ll a,ll b,ll &x,ll &y)
{   ll d=a;
if(b)
{d=ex_gcd(b,a%b,x,y);x-=(a/b)*y;swap(x,y);}
else x=1,y=0;
return d;
}
int main()
{
int t,cas=0;ll a,b,c,x1,x2,y1,y2,gcd,bb,ans,x0,y0,down,up;double maxn,minx;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld%lld%lld%lld%lld%lld",&a,&b,&c,&x1,&x2,&y1,&y2);
gcd=ex_gcd(a,b,x,y);c*=(-1);
if(a==0&&b==0){if(c==0)printf("Case %d: %lld\n",++cas,(x2-x1+1)*(y2-y1+1));else printf("Case %d: 0\n",++cas);continue;}
if(c%gcd!=0){printf("Case %d: 0\n",++cas);continue;}
if(a==0){if(c%b==0&&(c/b)>=y1&&(c/b)<=y2)printf("Case %d: %lld\n",++cas,x2-x1+1);else printf("Case %d: 0\n",++cas);continue;}
if(b==0){if(c%a==0&&(c/a)>=x1&&(c/a)<=x2)printf("Case %d: %lld\n",++cas,y2-y1+1);else printf("Case %d: 0\n",++cas);continue;}
bb=c/gcd;x*=bb;y*=bb;x0=b/gcd;y0=a/gcd;
if(x0>0)
{minx=(double)(x1-x)/x0;
maxn=(double)(x2-x)/x0;
down=ceil(minx);up=floor(maxn);}
else
{minx=(double)(x2-x)/x0;
maxn=(double)(x1-x)/x0;
down=ceil(minx);up=floor(maxn);}
if(y0>0)
{double tmp1,tmp2;
tmp1=(double)(y-y2)/y0;
tmp2=(double)(y-y1)/y0;
down=max(down,(ll)ceil(tmp1));up=min(up,(ll)floor(tmp2));
}
else
{double tmp1,tmp2;
tmp1=(double)(y-y1)/y0;
tmp2=(double)(y-y2)/y0;
down=max(down,(ll)ceil(tmp1));up=min(up,(ll)floor(tmp2));
}
if(down>up)ans=0;else ans=up-down+1;
printf("Case %d: %lld\n",++cas,ans);
}
}


Romantic

The Sky is Sprite.

The Birds is Fly in the Sky.

The Wind is Wonderful.

Blew Throw the Trees

Trees are Shaking, Leaves are Falling.

Lovers Walk passing, and so are You.

…………………………..Write in English class by yifenfei

Girls are clever and bright. In HDU every girl like math. Every girl like to solve math problem!

Now tell you two nonnegative integer a and b. Find the nonnegative integer X and integer Y to satisfy X*a + Y*b = 1. If no such answer print “sorry” instead.

Input

The input contains multiple test cases.

Each case two nonnegative integer a,b (0

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll x,y;
ll ex_gcd(ll a,ll b,ll &x,ll &y)
{   ll d=a;
if(b)
{d=ex_gcd(b,a%b,x,y);x-=(a/b)*y;swap(x,y);}
else x=1,y=0;
return d;
}
int main()
{
ll a,b,gcd,tmp,ci;
while(~scanf("%lld%lld",&a,&b))
{gcd=__gcd(a,b);
if(gcd!=1){printf("sorry\n");continue;}
else ex_gcd(a,b,x,y);
tmp=b/gcd;if(x>0)ci=x/tmp;else ci=(x/tmp)-1;
x-=ci*(b/gcd);
y+=ci*(a/gcd);
printf("%lld %lld\n",x,y);
}
}


青蛙的约会

两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面。它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止。可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置。不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的。但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的。为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面。

我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。

Input

输入只包括一行5个整数x,y,m,n,L,其中x≠y < 2000000000,0 < m、n < 2000000000,0 < L < 2100000000。

Output

输出碰面所需要的跳跃次数,如果永远不可能碰面则输出一行”Impossible”

剩余问题,(这里我把题目中x,y写为a,b来区分)转化一下可得x(n-m)+yl=a-b.

#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
ll x,y;
ll ex_gcd(ll a,ll b,ll &x,ll &y)
{   ll d=a;
if(b)
{d=ex_gcd(b,a%b,x,y);
x-=(a/b)*y;
swap(x,y);
}
else x=1,y=0;
return d;
}
int main()
{
ll a,b,m,n,l,d;
while(~scanf("%lld%lld%lld%lld%lld",&a,&b,&m,&n,&l))
{
d=ex_gcd(n-m,l,x,y);
if((a-b)%d){printf("Impossible");return 0;}
x=(x%(l/d)+(l/d)%(l/d));
printf("%d\n",(x*((a-b)/d)%l+l)%l);
}
}


Strange way to express integers

Elina is reading a book written by Rujia Liu, which introduces a strange way to express non-negative integers. The way is described as following:

Choose k different positive integers a1, a2, …, ak. For some non-negative m, divide it by every ai (1 ≤ i ≤ k) to find the remainder ri. If a1, a2, …, ak are properly chosen, m can be determined, then the pairs (ai, ri) can be used to express m.

“It is easy to calculate the pairs from m, ” said Elina. “But how can I find m from the pairs?”

Since Elina is new to programming, this problem is too difficult for her. Can you help her?

Input

The input contains multiple test cases. Each test cases consists of some lines.

Line 1: Contains the integer k.

Lines 2 ~ k + 1: Each contains a pair of integers ai, ri (1 ≤ i ≤ k).

Output

Output the non-negative integer m on a separate line for each test case. If there are multiple possible values, output the smallest one. If there are no possible values, output -1.

Sample Input

2

8 7

11 9

Sample Output

31

Hint

All integers in the input and the output are non-negative and can be represented by 64-bit integral types.

剩余问题一般化,可以用类似dp思想考虑.第一个传进来的余数肯定是此时答案,那么当第二个进来,第一个答案就不一定能满足,所以(k*a1+r1)≡r2(mod a2),那么又可以转化为标准的扩欧了:k*a1+kk*a2=r2-r1.

#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
ll x,y;
ll extgcd(ll a,ll b,ll &x,ll &y)
{   ll d=a;
if(!b)x=1,y=0;
else
{d=extgcd(b,a%b,x,y);
x-=(a/b)*y;
swap(x,y);
}
return d;
}
int main()
{int k,i;ll a,b,r,ans=0,tmp=0,now;bool ifok=0;
while(~scanf("%d",&k))
{ ans=0;tmp=0;ifok=0;
for(i=1;i<=k;i++)
{
scanf("%lld%lld",&a,&r);
if(i==1){ans=r;tmp=a;continue;}
else
{now=extgcd(tmp,a,x,y);
if((r-ans)%now)ifok=1;
else
{
x*=(r-ans)/now;
x%=a/now;
x+=a/now;
x%=a/now;
ans+=x*tmp;tmp=tmp*a/now;
}
}
}
ifok?printf("-1\n"):printf("%lld\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: