每行一个整数x,0<= x <= 2^31。
题目大意:
1.求方程x^a==b(mod N)解的数量,N是奇数
2.按照方程x^a==b(mod N)的解指示信鸽放飞时间将信鸽分组,每一组不少于k个信鸽,求总延迟最少的分组方法
大概做法:
1.将N分解因子,分解为p1^e1*p2^e2... ...,pi为素数,ei为正整数。
2.对于每一个pi^ei,求出xi^a=bi(mod pi^ei),式中bi=b%pi^ei(难)。可能有多解,需要算出xi的所有可能解。
3.判断解的总数,最终x^a==b(mod N)解的总数是所有xi^a=bi(mod pi^ei)解总数的乘积)。特判解总数为0的情况,解总数
4.枚举所有xi的取值组合,使用中国剩余定理还原出对应的x,x是原方程x^a==b(mod N)的解。
5.对所有解排序,使用动态规划解出最小扣押延迟
难点:
求xi^a=bi(mod pi^ei)的所有解:
若bi==0:
xi包含p^((ei+a-1)/a)的因子为充要条件,枚举之p^((ei+a-1)/a)的倍数
ei==1时:
求pi的一个原根r,求r为底b的离散对数l,则r^l==bi(mod pi),则(r^(l/a))^a=r^l=b(mod pi),xi=r^(l/a),l/a实在mod phi(p)环境下的除法,可能多解或无解
ei!=1时:
若bi,pi互素,做法与e==1相同
若bi,pi不互素,有bi=pi^c *d,c不整除a则无解,否则设x=pi^(c/a)*y,y^a=d(mod pi^(ei-c)),求出所有y,即可求出x。注意要求出所有x,[0,pi^ei-1]范围内的所有x,不要漏掉
因子分解:暴力,略。
中国剩余定理:见相关资料,原理略。主要是用中国剩余定理从分解因子后的各个xi^a=bi(mod pi^ei)方程的解还原出原始的x^a==b(mod N)的解,小心中间过程溢出
动态规划:
纯暴力不行。需要斜率优化,或者二分优化。实际上加上决策点的剪枝(对i的决策只从>=i-1的决策点里面枚举)就能通过此题。
复杂度:
分解因子、离散对手:O(sqrt(n));
斜率优化的动态规划:O(ans),ans为方程解的个数,ans<=m
但动态规划前的排序复杂度为O(ans*log(ans)),是最慢的部分,可以考虑用针对整数的线性算法优化(标程没有优化)
把十进制整数转换为十六进制,格式为0x开头,10~15由大写字母A~F表示。
每行一个整数x,0<= x <= 2^31。
每行输出对应的八位十六进制整数,包括前导0。
0 1023
0x00000000 0x000003FF
#include
#include
#include
int main()
{
int x;
while(scanf("%d", &x) != EOF)
printf("0x%08X\n", x);
return 0;
}
Time Limit: 1 Sec Memory Limit: 16 MBSUBMIT: 294 Solved: 111
Description
Sometimes Ziwen need to operate even larger numbers. A limit of 1000 digits is so small… You have to find the sum of two numbers with maximal size of 1 000 000 digits.
The first line contains a single integer N that is the length of the given integers(1 ≤ N ≤ 1 000 000). It is followed by these integers written in columns. That is, the next N lines contain two digits each, divided by a space. Each of the two given integers is not less than 0, and the length of their sum does not exceed N. The integers may contain leading zeroes.
Output exactly N digits in a single line representing the sum of these two integers.
40 44 26 83 7
4750
#include
#include
#include
const int maxn = 1 << 20;
int a[maxn], b[maxn], n;
int main()
{
int i, cur;
while(scanf("%d", &n) != EOF)
{
for(i = n - 1; i >= 0; -- i)
scanf("%d%d", &a[i], &b[i]);
for(i = cur = 0; i < n; ++ i)
{
a[i] += b[i] + cur;
cur = a[i] / 10;
a[i] %= 10;
}
for(i = n - 1; i >= 0; -- i)
printf("%d", a[i]);
printf("\n");
}
return 0;
}
Time Limit: 1 Sec Memory Limit: 128 MB
SUBMIT: 431 Solved: 80
Description
Mr. Mindless has many balls and many boxes,he wants to put all the balls into some of the boxes.Now, he wants to know how many different solutions he can have.
you know,he could put all the balls in one box,and there could be no balls in some of the boxes.Now,he tells you the number of balls and the numbers of boxes, can you to tell him the number of different solutions? Because the number is so large, you can just tell him the solutions mod by a given number C.
Both of boxes and balls are all different.
For each testcase,output an integer,denotes the number you will tell Mr. Mindless
3 2 44 3 5
14
#include
#include
#include
typedef long long LL;
LL box, ball, c;
LL MultiMod(LL a, LL b, LL c)
{
LL res = 0;
if(!b) return 0;
while(b > 1)
{
if(b & 1) res = (res + a) % c;
a = (a << 1) % c;
b >>= 1;
}
return (res + a) % c;
}
LL PowMod(LL a, LL b, LL c)
{
LL res = 1;
while(b > 1)
{
if(b & 1) res = MultiMod(res, a, c);
a = MultiMod(a, a, c);
b >>= 1;
}
return MultiMod(res, a, c);
}
int main()
{
while(scanf("%lld%lld%lld", &box, &ball, &c) != EOF)
printf("%lld\n", PowMod(box, ball, c));
return 0;
}
Time Limit: 1 Sec Memory Limit:128 MB
SUBMIT: 457 Solved: 86
求出熬制所成孟婆汤的药效b[i],每碗孟婆汤后以换行结尾。
5 11 2 7 5 3 9 3 7 9 8 5
10 6 4 3 1 5 3 2
#include
#include
#include
const int maxn = 1 << 17;
typedef long long LL;
int a[maxn], b[maxn], n, m;
void ReadData()
{
int i;
for(i = 0; i < n; ++ i)
scanf("%d", &a[i]);
}
void Pre()
{
int i;
for(i = n - 1, b[n] = 1; i >= 0; -- i)
b[i] = (LL)b[i + 1] * a[i] % m;
for(i = 1; i < n; ++ i)
a[i] = (LL)a[i - 1] * a[i] % m;
}
void Prin()
{
int i;
printf("%d", b[1] % m);
for(i = 1; i < n; ++ i)
printf(" %d", (LL)a[i - 1] * b[i + 1] % m);
printf("\n");
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF)
{
ReadData();
Pre();
Prin();
}
return 0;
}
Time Limit: 1 Sec Memory Limit: 128 MB
SUBMIT: 157 Solved: 45
First |
200 |
BFirst |
-200 |
Second |
275 |
BSeconde |
-275 |
Spree |
325 |
BSpree |
-325 |
Dominating |
400 |
BDominating |
-400 |
Mega |
475 |
BMega |
-475 |
Unstop |
575 |
BUnstop |
-575 |
Wicked |
675 |
BWicked |
-675 |
Monster |
800 |
BMonser |
-800 |
God |
900 |
BGod |
-900 |
Holy |
1000 |
BHoly |
-1000 |
多组测试数据,每组数据有多行,开始10行表示每个玩家的名字,前5个为近卫的玩家,后5个为天灾的玩家,接下来有一行,一个数字N(N<=100)表示接下来有多少行杀和被杀的数据,接下来有N行,每行有两个玩家的名字(用空格隔开),表示前面那个玩家杀死后面那个玩家。所有的玩家姓名为不超过15个字符的字符串
对于每组测试数据,按照输入的顺序输出每个玩家最后的金钱数目,每个玩家一行,表示他的金钱
PN
klion26
wdy0504
EX
Kelp
pkudream
wxt
Kaer
CC
STHM
7
PN pkudream
EX wxt
wdy0504 Kaer
CC Kelp
klion26 STHM
wxt PN
wxt EX
4726
4926
4926
4726
4526
4526
5001
4526
4926
4526
#include
#include
#include
int K[11] = {0, 200, 275, 325, 400, 475, 575, 675, 800, 900, 1000};
int trie[200][128], tp, bh;
int situ[11], money[11];
char name[10][20], w[20], l[20];
int MakeT(char *x)
{
int i, t, cur = 0;
for(i = 0; x[i]; ++ i)
{
if(trie[cur][x[i]] == -1)
trie[cur][x[i]] = ++ tp;
cur = trie[cur][x[i]];
}
if(trie[cur][0] == -1) trie[cur][0] = bh ++;
return trie[cur][0];
}
void win(char *x)
{
int ith = MakeT(x);
if(situ[ith] < 0)
situ[ith] = 0;
++ situ[ith];
if(situ[ith] > 10) situ[ith] = 10;
money[ith] += K[situ[ith]];
}
void lose(char *x)
{
int ith = MakeT(x);
if(situ[ith] > 0)
situ[ith] = 0;
-- situ[ith];
if(situ[ith] < -10) situ[ith] = -10;
money[ith] -= K[-situ[ith]];
if(money[ith] < 0) money[ith] = 0;
}
int main()
{
int i, j, k, n;
while(scanf("%s", name[0]) != EOF)
{
tp = bh = 0;
memset(trie, -1, sizeof(trie));
situ[MakeT(name[0])] = 0, money[0] = 4726;
for(i = 1; i < 10; ++ i)
{
scanf("%s", name[i]);
situ[MakeT(name[i])] = 0;
money[i] = 4726;
}
scanf("%d", &n);
while(n --)
{
scanf("%s%s", w, l);
if(MakeT(w) == MakeT(l)) continue;
if(MakeT(w) / 5 != MakeT(l) / 5)
win(w);
lose(l);
}
for(i = 0; i < 10; ++ i)
printf("%d\n", money[i]);
}
return 0;
}
Time Limit: 1 Sec Memory Limit:32 MB
SUBMIT: 248 Solved: 65
Given three integer sequences which have been sorted in ascending order,pick one integer from each sequence and we can get three integers.we want these three integers to be nearest to each other.Assuming these three integers as a,b,c, they are nearest to each other means d=(a-b)2+(b-c)2+(c-a)2 is the smallest.
For each test case, just print one integer : the smallest d as mentioned above.
10 10 10 1 2 3 4 5 6 7 8 9 10 2 3 6 8 10 12 14 16 18 20 3 5 7 9 11 12 14 16 18 20
0
#include
#include
#include
const int maxn = 1 << 20;
typedef long long LL;
LL a[maxn], b[maxn], c[maxn];
inline LL min(LL x, LL y)
{return x < y ? x : y;}
inline LL cal(LL x, LL y, LL z)
{return (x - y) * (x - y) + (x - z) * (x - z) + (z - y) * (z - y);}
int main()
{
LL ans, tmpa, tmpb, tmpc;
int n1, n2, n3, i, j, k;
while(scanf("%d%d%d", &n1, &n2, &n3) != EOF)
{
for(i = 0; i < n1; ++ i) scanf("%lld", &a[i]);
for(i = 0; i < n2; ++ i) scanf("%lld", &b[i]);
for(i = 0; i < n3; ++ i) scanf("%lld", &c[i]);
ans = ((LL)1 << 63) - 1;
i = j = k = 0;
while(i < n1 && j < n2 && k < n3 && ans > 0)
{
ans = min(ans, cal(a[i], b[j], c[k]));
tmpa = cal(a[i + 1], b[j], c[k]);
tmpb = cal(a[i], b[j + 1], c[k]);
tmpc = cal(a[i], b[j], c[k + 1]);
if(tmpa < tmpb && tmpa < tmpc) ++ i;
else if(tmpb < tmpc) ++ j;
else ++ k;
}
printf("%lld\n", ans);
}
return 0;
}
Time Limit: 2 Sec Memory Limit: 128 MB
SUBMIT: 21 Solved: 6
最近Grandeur买了两个魔方,拆开包裹的时候,室友都围了过来。“还有这种魔方,这多简单……”。因为有一个二阶魔方,别看它小,也不是好欺负的。Grandeur把魔方转动了几下递给他,说道“就不用完全复原了,你把上下相对的黄色和白色两个面弄出来试试咯。”于是他掰了一下午……
原来二阶魔方也不是那么简单的。Grandeur现在想知道对于一个特定的情况,最少需要几步可以达到黄白两面复原的状态呢(任意面任意方向旋转90度为一步)?
每组数据输出一个整数,表示达到目标状态需要的最少步数。
24 4 1 2 0 4 3 4 2 0 2 0 0 3 5 5 5 1 5 2 3 3 1 14 4 4 4 0 0 3 3 2 2 0 0 5 5 5 5 1 1 2 2 3 3 1 1
21
编号只是方便描述数据,复原的魔方不一定要颜色和图中编号一一对应的。
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int HashMax = 1000003;
const int inf = 0x3f3f3f3f;
int ans[HashMax];
LL Hash[HashMax];
int ye, wh;
int RO[6][24]= {
{0,9,2,11,4,5,6,7,8,13,10,15,12,22,14,20,18,16,19,17,3,21,1,23},
{0,22,2,20,4,5,6,7,8,1,10,3,12,9,14,11,17,19,16,18,15,21,13,23},
{0,1,7,5,4,12,6,13,10,8,11,9,18,16,14,15,2,17,3,19,20,21,22,23},
{0,1,16,18,4,3,6,2,9,11,8,10,5,7,14,15,13,17,12,19,20,21,22,23},
{0,1,2,3,4,5,22,23,8,9,6,7,14,12,15,13,16,17,10,11,20,21,18,19},
{0,1,2,3,4,5,10,11,8,9,18,19,13,15,12,14,16,17,22,23,20,21,6,7}
};
int MakeHash(int y, int w)
{
LL situ = (LL)y << 24 | w, big = situ % HashMax;
while(Hash[big] != -1 && Hash[big] != situ)
big = (big << 1 | 1) % HashMax;
if(Hash[big] == -1) Hash[big] = situ;
return big;
}
inline int min(int a, int b)
{return a < b ? a : b;}
struct S
{int y, w, pace;};
queue q;
void bfs()
{
S lin, nex;
int i, j, situ;
lin.pace = 0;
lin.y = 0xf0000, lin.w = 0xf0, q.push(lin);
ans[MakeHash(lin.y, lin.w)] = 0;
lin.y = 0xf0, lin.w = 0xf0000, q.push(lin);
ans[MakeHash(lin.y, lin.w)] = 0;
lin.y = 0xf00000, lin.w = 0xf00, q.push(lin);
ans[MakeHash(lin.y, lin.w)] = 0;
lin.y = 0xf00, lin.w = 0xf00000, q.push(lin);
ans[MakeHash(lin.y, lin.w)] = 0;
lin.y = 0xf000, lin.w = 0xf, q.push(lin);
ans[MakeHash(lin.y, lin.w)] = 0;
lin.y = 0xf, lin.w = 0xf000, q.push(lin);
ans[MakeHash(lin.y, lin.w)] = 0;
while(!q.empty())
{
lin = q.front(), q.pop();
for(i = 0; i < 6; ++ i)
{
nex.y = nex.w = 0;
for(j = 0; j < 24; ++ j)
{
nex.y |= (lin.y >> RO[i][j] & 1) << j;
nex.w |= (lin.w >> RO[i][j] & 1) << j;
}
nex.pace = lin.pace + 1;
situ = MakeHash(nex.y, nex.w);
if(ans[situ] == -1)
{
ans[situ] = nex.pace;
q.push(nex);
}
}
}
}
int main()
{
int i, j, T;
memset(Hash, -1, sizeof(Hash));
memset(ans, -1, sizeof(ans));
bfs();
for(scanf("%d", &T); T --; )
{
for(i = ye = wh = 0; i < 24; ++ i)
{
scanf("%d", &j);
if(j == 0) ye |= 1 << i;
if(j == 1) wh |= 1 << i;
}
printf("%d\n", ans[MakeHash(ye, wh)]);
}
return 0;
}
Time Limit: 1 Sec Memory Limit: 64 MB
SUBMIT: 79 Solved: 29
His mission is just need to shut down several valves, making somebody's water outlets no longer have the water out, so that he can repair the family's water pipes. There are a total of T families' water pipes need to repair, but he needs to repair them one by one. In order to improve the efficiency, he wants to know how many valves at least he needs to turn off to cut the target family's water supply.
For each test case,just print the least number of the valves that need to be shut down.If there's no solution to let the target outlet be without water,then just print "No solution!" instead.After each test case,print a blank line.
9 5 11 6 2 0 6 1 5 6 11 11 10 5 8 8 3 7 9 7 2 12 13 9 12 4 13 5 6 7 10 8 9 12 11 10 13 1 2 1 2 17 7 19 11 2 0 9 9 13 13 23 1 7 2 10 3 14 4 15 14 15 15 16 16 22 6 21 8 21 17 18 18 19 7 19 12 22 11 12 20 22 23 10 7 8 10 11 14 17 16 18 5 20 21 23 8 9 12 13 11 17 20 19 21 13 3 2
3 4 3 No solution!
#include
#include
#include
#include
using namespace std;
const int maxn = 1 << 11;
const int maxm = 1 << 14;
int p[maxn], fst[maxn], lay[maxn], work[maxn], M, N, L, K, T, wnum, sou, ter;
int flow[maxm], cap[maxm], u[maxm], v[maxm], nex[maxm];
void init()
{
int i;
for(i = M + N; i >= 0; -- i) p[i] = i;
memset(fst, -1, sizeof(fst));
wnum = 0;
}
int fa(int i)
{return p[i] == i ? i : p[i] = fa(p[i]);}
void AddEdge(int s, int e)
{
u[wnum] = s;
v[wnum] = e;
cap[wnum] = 1;
nex[wnum] = fst[s];
fst[s] = wnum;
++ wnum;
}
void DbEdge(int s, int e)
{
AddEdge(s, e);
AddEdge(e, s);
}
void ReadGraph()
{
int s, e;
while(L --)
{
scanf("%d%d", &s, &e);
p[fa(s)] = fa(e);
}
while(K --)
{
scanf("%d%d", &s, &e);
DbEdge(fa(s), fa(e));
}
}
/********************网络流 ********************/
inline int min(int a, int b)
{return a < b ? a : b;}
queue q;
const int inf = 0x3f3f3f3f;
int bfs()
{
int i, j;
while(!q.empty()) q.pop();
memset(lay, -1, sizeof(lay));
q.push(sou), lay[sou] = 0;
while(!q.empty())
{
for(i = fst[q.front()], q.pop(); i != -1; i = nex[i])
if(cap[i] > flow[i] && lay[v[i]] == -1)
{
lay[v[i]] = lay[u[i]] + 1;
if(v[i] == ter)
return 1;
q.push(v[i]);
}
}
return 0;
}
int dfs(int cur, int inc)
{
if(cur == ter)
return inc;
for(int &i = work[cur]; i != -1; i = nex[i])
if(flow[i] < cap[i] && lay[v[i]] == lay[cur] + 1)
if(int t = dfs(v[i], inc < cap[i] ? inc : cap[i]))
{
flow[i] += t;
flow[i ^ 1] -= t;
return t;
}
return 0;
}
int dinic()
{
int res = 0, t;
memset(flow, 0, sizeof(flow));
while(bfs())
{
memcpy(work, fst, sizeof(fst));
while(t = dfs(sou, inf))
res += t;
}
return res;
}
/********************网络流 ********************/
void MakeAns()
{
sou = fa(0);
while(T --)
{
scanf("%d", &ter);
ter = fa(ter);
if(sou == ter)
printf("No solution!\n");
else
printf("%d\n", dinic());
}
}
int main()
{
while(scanf("%d%d%d%d%d", &M, &N, &L, &K, &T) != EOF)
{
init();
ReadGraph();
MakeAns();
printf("\n");
}
return 0;
}
鸡姨和刚妈 正准备下个周末的Party。他们想邀请很多的朋友,其中有很多男生,也有很多女生,大家一起交流感情。她们家中有很多桌子,其中有一个很大圆桌,大家都要到这个圆桌上来玩。但是 鸡姨和刚妈 现在不知道如何分配座次,这是为什么呢?据说当有超过K个女孩座位相邻(即这些女孩的座位是连续的,中间没有男孩)的话,她们就会说一整晚的话而不和其他人聊天,男生们会因此很寂寞,也达不到Party的目的。鸡姨和刚妈 没有其他选择,只有求助她们的好朋友Ziwen。
33 13 34 1
243
第一组数据的方案是:MMM,MMW (M是男孩, W是女孩)。
第二组数据的方案是:MMM,MMW,MWW,WWW。
第三组数据的方案是:MMMM, MMMW,MWMW。
#include
#include
using namespace std;
const int MaxN=2000;
const long long ModNum=100000007;
long long P[MaxN+1][MaxN+1],R[MaxN+1],Pow[MaxN+1],Ans;
int Loo,Loop,N,K;
long long ModExp(long long Base,long long T)
{
if(T==0)
return 1;
long long Res=ModExp(Base,T>>1);
Res=(Res*Res)%ModNum;
if((T&1)==1)
Res=(Res*Base)%ModNum;
return Res;
}
void First()
{
for(int i=1;i<=MaxN;i++)
Pow[i]=ModExp(i,ModNum-2);
}
void Init()
{
scanf("%d%d",&N,&K);
K=min(K,N);
}
void Work()
{
int i,j;
P[1][0]=1;
for(i=1;i=N)
Ans=1;
else
Ans=0;
for(i=1;i<=N;i++)
if((N%i)==0)
{
for(j=2*i;j<=N;j+=i)
R[j]=(R[j]-R[i]+ModNum)%ModNum;
Ans=(Ans+R[i]*Pow[i])%ModNum;
}
}
void Print()
{
printf("%lld\n",Ans);
}
int main()
{
First();
scanf("%d",&Loop);
for(Loo=1;Loo<=Loop;Loo++)
{
Init();
Work();
Print();
}
return 0;
}
很久很久以前,有一位将军被派到前线指挥战斗。前线离都城很遥远,将军希望使用信鸽向都城汇报战况。
第一行一个整数T(1<=T<=50),表示数据的组数。
每组测试数据输出一行,每行两个整数,第一个整数表示按照将军计划,将要发出的信鸽数量;第二个数表示信鸽被扣留在营地造成的最少总延迟(分钟数)。如果将军带去的信鸽数不够,第二个数输出-1;如果将军带去的信鸽足够,但营地无法将这些信鸽分组发回都城,第二个数输出-2。如果按照将军的计划,根本不需要发送信鸽,仍然算是可以成功发送的,扣留的总延迟为0(两个数都输出0)。
5 13 2 4 3 10 125 2 2 25 100 225 10 60 1 1000 1517 100 7 103 10000 1000003 10 1000002 1 1000000
4 2 10 75 120 1020 1 -2 1000002 -1
#include
#include
#include
#include
using namespace std;
typedef long long U64;
const int MAXF = 16;
const int MAX_ANS = 100005;
int fact_val[MAXF];
int fact_cnt[MAXF];
int fact_pow[MAXF];
int ans_cnt[MAXF];
int ans_array[MAXF][MAX_ANS];
int g_fact_num, g_tot_cnt, g_n, g_k, g_m, g_a, g_b;
int china_x[MAXF], china_Mi[MAXF];
int S[MAX_ANS], A[MAX_ANS], g_final_p;
U64 sum[MAX_ANS], dp[MAX_ANS];
const int HZ = 43963;
const int MXB = 200000;
struct node
{
int key;
int val;
node *next;
};
node BUF[MXB], *BP;
node *hash[HZ];
int pow_mod(int a, int b, int n)
{
int res = 1;
while (b)
{
if (b & 1)
res = (U64) res * a % n;
a = (U64) a * a % n;
b >>= 1;
}
return res;
}
int ext_gcd(int a, int b, int &x, int &y)
{
int t, res;
if (b == 0)
{
x = 1, y = 0;
return a;
}
res = ext_gcd(b, a % b, x, y);
t = x, x = y, y = t - a / b*y;
return res;
}
int primitiv_root(int p)
{
int res, i, arr[20], fn = 0, phi = p - 1;
for (i = 2; i * i <= phi; i++)
{
if (phi % i == 0)
{
arr[fn++] = i;
while (phi % i == 0)
phi /= i;
}
}
if (phi > 1)arr[fn++] = phi;
for (res = 2; res < p; res++)
{
for (i = 0; i < fn; i++)
if (pow_mod(res, (p - 1) / arr[i], p) == 1)
break;
if (i >= fn)
{
if (res % 2 == 0)
res += p;
if (pow_mod(res, p - 1, p * p) == 1)
res += 2 * p;
break;
}
}
return res;
}
inline void insert(int key, int val)
{
int k = key % HZ;
BP->key = key;
BP->val = val;
BP->next = hash[k];
hash[k] = BP++;
}
inline int find(int key)
{
for (node *p = hash[key % HZ]; p != NULL; p = p->next)
{
if (p->key == key)
return p->val;
}
return -1;
}
int log_mod(int a, int b, int n, int phi_n)
{
int i, e, T, iv, v, x, y;
if (b == 1)return 0;
T = (int) (sqrt((double) phi_n) + 1.0);
iv = pow_mod(a, T, n);
ext_gcd(iv, n, x, y);
v = (x + n) % n;
memset(hash, 0, sizeof (hash));
BP = BUF;
for (e = 1, i = 0; i < T; i++)
{
if (find(e) != -1)
break;
insert(e, i);
e = ((long long) e * a) % n;
}
for (i = 0; i < T; i++)
{
if ((e = find(b)) != -1)
return i * T + e;
b = ((long long) b * v) % n;
}
return -1;
}
int calc_all_atom()
{
int idx;
g_tot_cnt = 1;
for (idx = 0; idx < g_fact_num; idx++)
{
int a = g_a, b = g_b % fact_pow[idx], p = fact_val[idx];
if (b == 0)
{
int temp_a = pow_mod(p, (fact_cnt[idx] + a - 1) / a, g_n);
ans_cnt[idx] = fact_pow[idx] / temp_a;
g_tot_cnt *= ans_cnt[idx];
if (g_tot_cnt > g_m)
{
continue;
}
for (int i = 0; i * temp_a < fact_pow[idx]; i++)
{
ans_array[idx][i] = i*temp_a;
}
} else
{
int g = __gcd(b, fact_pow[idx]);
int log_g = 0;
while (pow_mod(p, log_g, g_n) != g)log_g++;
if (log_g % a != 0)
{
return (g_tot_cnt = 0);
}
int ans_ext_fact = pow_mod(p, log_g / a, g_n);
int temp_b = b / g;
int temp_mod_base = fact_pow[idx] / g;
int phi_base = temp_mod_base - temp_mod_base / p;
int temp_a, x, y;
temp_a = ext_gcd(a, phi_base, x, y);
if (pow_mod(temp_b, (phi_base) / temp_a, temp_mod_base) != 1)
{
return (g_tot_cnt = 0);
}
ans_cnt[idx] = temp_a * (g / ans_ext_fact);
g_tot_cnt *= ans_cnt[idx];
if (g_tot_cnt > g_m)continue;
temp_b = pow_mod(temp_b, x + phi_base, temp_mod_base);
int ans, step;
if (temp_a == 1)
{
ans = temp_b;
step = 1;
} else
{
int r = primitiv_root(p) % temp_mod_base;
int log_b = log_mod(r, temp_b, temp_mod_base, phi_base);
ans = pow_mod(r, log_b / temp_a, temp_mod_base);
step = pow_mod(r, phi_base / temp_a, temp_mod_base);
}
for (int i = 0; i * ans_ext_fact < g; i++)
{
for (int j = 0; j < temp_a; j++)
{
ans_array[idx][i * temp_a + j] = (ans + i * temp_mod_base) * ans_ext_fact;
ans = (U64) ans * step % temp_mod_base;
}
}
}
}
return g_tot_cnt;
}
void ana(int n)
{
g_fact_num = 0;
for (int i = 3; i * i <= n; i += 2)
{
if (n % i == 0)
{
fact_val[g_fact_num] = i;
fact_cnt[g_fact_num] = 0;
fact_pow[g_fact_num] = 1;
do
{
n /= i;
fact_cnt[g_fact_num]++;
fact_pow[g_fact_num] *= i;
}
while (n % i == 0);
g_fact_num++;
}
}
if (n > 1)
{
fact_val[g_fact_num] = n;
fact_pow[g_fact_num] = n;
fact_cnt[g_fact_num++] = 1;
}
}
void china_dfs(int deep, int res)
{
for (int i = 0; i < ans_cnt[deep]; i++)
{
U64 x = china_x[deep];
int Mi = china_Mi[deep];
int mi = fact_pow[deep];
int nres = (res + (x * (U64) ans_array[deep][i] % mi) * Mi) % g_n;
if (deep == g_fact_num - 1)
{
A[g_final_p++] = nres;
} else
{
china_dfs(deep + 1, nres);
}
}
}
void calc_final_ans()
{
int i, x, y;
for (i = 0; i < g_fact_num; i++)
{
china_Mi[i] = g_n / fact_pow[i];
ext_gcd(china_Mi[i], fact_pow[i], x, y);
china_x[i] = (x + fact_pow[i]) % fact_pow[i];
}
g_final_p = 0;
china_dfs(0, 0);
}
inline double slope(int x, int y)
{
return ((double) dp[y] + (double) sum[y] - (double) dp[x] - (double) sum[x]) / (y - x);
}
U64 dp_solve(int n, int k)
{
int i, t, L = 0, R = -1;
sort(A, A + n);
sum[0] = A[0];
for (i = 1; i < n; i++)
{
sum[i] = A[i] + sum[i - 1];
}
for (i = k - 1; i < n && i < k + k - 1; i++)
dp[i] = A[i]*(U64) (i + 1) - sum[i];
for (; i < n; i++)
{
while (L < R && slope(S[R - 1], S[R]) >= slope(S[R], i - k))R--;
S[++R] = i - k;
while (L < R && slope(S[L], S[L + 1]) < A[i]) L++;
t = S[L];
dp[i] = dp[t] + A[i]*(U64) (i - t)-(sum[i] - sum[t]);
}
return dp[n - 1];
}
int main()
{
int t;
U64 res;
scanf("%d", &t);
while (t--)
{
scanf("%d%d%d%d%d", &g_n, &g_k, &g_a, &g_b, &g_m);
ana(g_n);
calc_all_atom();
if (g_tot_cnt == 0)
{
res = 0;
} else if (g_tot_cnt > g_m)
{
res = -1;
} else if (g_tot_cnt < g_k)
{
res = -2;
} else
{
calc_final_ans();
res = dp_solve(g_tot_cnt, g_k);
}
printf("%d %lld\n", g_tot_cnt, res);
}
return 0;
}