Problem Description
One day, a useless calculator was being built by Kuros. Let's assume that number X is showed on the screen of calculator. At first, X = 1. This calculator only supports two types of operation.
1. multiply X with a number.
2. divide X with a number which was multiplied before.
After each operation, please output the number X modulo M.
Input
The first line is an integer T( 1≤T≤10 ), indicating the number of test cases.
For each test case, the first line are two integers Q and M. Q is the number of operations and M is described above. ( 1≤Q≤105,1≤M≤109 )
The next Q lines, each line starts with an integer x indicating the type of operation.
if x is 1, an integer y is given, indicating the number to multiply. ( 0<y≤109 )
if x is 2, an integer n is given. The calculator will divide the number which is multiplied in the nth operation. (the nth operation must be a type 1 operation.)
It's guaranteed that in type 2 operation, there won't be two same n.
Output
For each test case, the first line, please output "Case #x:" and x is the id of the test cases starting from 1.
Then Q lines follow, each line please output an answer showed by the calculator.
题意:多组数据。该题是模拟了一个计算器的乘除算法。对于每组数据首先输入操作次数q和要取模的数mod,接下来q行,每行先输入x表示要进行哪种操作,如果x=1,则再输入y,表示要进行乘法运算,要乘的因子为y,然后输出此次运算后所得数再对mod取余的结果;如果x=2,则再输入n,表示要进行除法运算,要除以第n此操作的那个因子,然后输出此次运算后所得数再对mod取余的结果。(sum从1开始。)
思路:刚开始以为是边计算边取余边类乘数,所以就很快敲出代码过了样例就交了,然而结果是WA,接着就找bug呀bug,最后则了这么一组样例:
输入:2 1000000000
1 1000000000
2 1
错误输出: 0
0
还好,找出了过不了的测试数据,然后就发现不能直接将取余后的结果直接赋给sum,因为如果取余后出现了0,则sum就会一直等于0,所以开始该思路,想着不取余了,光在输出的时候取余,问题来了,如果一直乘的话肯定会超long long,所以就想到了用大数模拟乘法和除法然后再取余,然后以TL告终,好吧,这个方法也不行,实在是没辙了,赛后询问大神,没想到大神那么短的代码就过了。详细内容还是看代码吧。
1 1000000000
2 1
错误输出: 0
0
正确输出: 0
1还好,找出了过不了的测试数据,然后就发现不能直接将取余后的结果直接赋给sum,因为如果取余后出现了0,则sum就会一直等于0,所以开始该思路,想着不取余了,光在输出的时候取余,问题来了,如果一直乘的话肯定会超long long,所以就想到了用大数模拟乘法和除法然后再取余,然后以TL告终,好吧,这个方法也不行,实在是没辙了,赛后询问大神,没想到大神那么短的代码就过了。详细内容还是看代码吧。
Sample Input
1 10 1000000000 1 2 2 1 1 2 1 10 2 3 2 4 1 6 1 7 1 12 2 7
Sample Output
Case #1: 2 1 2 20 10 1 6 42 504 84
<span style="font-size:18px;">#include <cstdio>
#include <algorithm>
#include <cstring>
#define ll long long
using namespace std;
ll q,mod,y[101000],x[101000]; //x[i]数组存储当前位置经计算后所得的sum值,y[i]数组存储当前操作所要操作的数
bool vis[101000]; //标记除数和除法操作的位置
void cc(int s,int e) //处理除法操作的函数
{
for(int i=s;i<=e;i++) //从除数的位置到当前位置除了要除的数和除法的操作再重新处理一下x数组
{
x[i]=x[i-1];
if(vis[i])
continue;
x[i]=(x[i-1]*y[i])%mod;
}
}
int main()
{
int t,xx;
scanf("%d",&t);
for(int k=1;k<=t;k++)
{
memset(vis,0,sizeof(vis)); //一定要记得清空vis数组呀
scanf("%lld %lld",&q,&mod);
printf("Case #%d:\n",k);
x[0]=1; //记得初始化x[0]
for(int i=1;i<=q;i++)
{
scanf("%d %lld",&xx,&y[i]);
if(xx==1)
{
x[i]=(x[i-1]*y[i])%mod;
printf("%I64d\n",x[i]);
}
else
{
vis[y[i]]=true; //只要是除数和除法操作都要标记一下
vis[i]=true;
cc(y[i],i);
printf("%I64d\n",x[i]);
}
}
}
return 0;
}
</span>