Number theory
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; }