Number theory
TimeLimit:2000MS MemoryLimit:524MB
64-bit integer IO format:
%I64d
Problem Description
Given a integers x = 1, you have to apply Q (Q ≤ 100000) operations: Multiply, Divide.
Input
First line of the input file contains an integer T(0 < T ≤ 10) that indicates how many cases of inputs are there.
The description of each case is given below:
The first line contains two integers Q and M. The next Q lines contains the operations in ith line following form:
M yi: x = x * yi.
N di: x = x / ydi.
It’s ensure that di is different. That means you can divide yi only once after yi came up.
0 < yi ≤ 10^9, M ≤ 10^9
Output
For each operation, print an integer (one per line) x % M.
SampleInput
1 10 1000000000 M 2 D 1 M 2 M 10 D 3 D 4 M 6 M 7 M 12 D 7
SampleOutput
2 1 2 20 10 1 6 42 504 84
这题的题意就是说给你t组数据,每组数据Q次查询,对于每次查询的结果对M取余数;
对于每次的查询,给你M z,表示x(每组数据起始x=1)更新为x*z,N di表示当前的x除以第di行的M 后面的值;
每次查询的结果对常量M取余
思路:由于每次查询结果要取余,这里我们很容易就想到逆元的做法,但是假如除数和取余数不互质的话,这里逆元就不存在了,因此行不通;
关于这题,我们可以把要乘的数当成我们所要得到的答案的因子,用线段树来维护答案x(即为root结点),root结点的值必定为所有数的积,这里每个数只会出现
一次,所有除以某个数我们可以把那个对应的因子变为1,相当于这个数对x没有贡献了。
#include<stdio.h>
#include<string.h>
using namespace std;
#define LL long long
const int maxn=1e6+5;
int mod;
struct node
{
int l,r;
LL num;
}T[maxn*4];
void push_up(int rt)
{
T[rt].num=T[rt<<1].num%mod*T[rt<<1|1].num%mod%mod;
}
void build(int rt,int l,int r)
{
T[rt].l=l;
T[rt].r=r;
if(l==r)
{
T[rt].num=1;
return ;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
push_up(rt);
}
void update(int rt,int x,int val)///找到下标为x处更新为val
{
if(T[rt].l==x&&T[rt].r==x)
{
T[rt].num=val;
return ;
}
int mid=(T[rt].l+T[rt].r)/2;
if(x <= mid)
update(rt<<1,x,val);
else
update(rt<<1|1,x,val);
push_up(rt);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int q;
scanf("%d %d",&q,&mod);
build(1,1,q);
for(int i=1;i<=q;i++)
{
getchar();
char c;
int x;
scanf("%c %d",&c,&x);
if(c=='M')
{
update(1,i,x);
printf("%I64d\n",T[1].num);
}
else
{
update(1,x,1);
printf("%I64d\n",T[1].num);
}
}
}
return 0;
}