版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liufengwei1/article/details/82024725
这题新人队2小时就A了,然后我队中期这题根本不知道怎么办,全机房都会做,于是ljn开始写mod质因数分解一蛤,mod的质因数单独拿出来算,mod<1e9所以最多30个不同的因数,因为2^30>1e9,然后对每一个mod的因数开个mp[j]存数字,cnt[j]存mp[j]在答案中的幂次,对于每一个乘起来的数a[i]我们都把里面mod的质因数给剔到cnt[j]中,然后不是mod的因数就与mod互质,就可以用飞马小定理求逆元了,就直接去算,然后每次都扫一遍cnt[j]得出mod的质因数的乘积,乘以剔除mod的质因数的质因数,然后取mod,就是没事的,这样做比线段树还快一点,考完以后一问他们,全是线段树,线段树的区间合并完美解决%mod=0的情况
#include<cstdio>
#include<cstring>
#include<vector>
#define maxl 100010
using namespace std;
int n;long long mod;
int primes[maxl], vis[maxl];
int mp[100], cnt[100];
long long a[maxl];
vector <long long > p[100];
char s[5];
void getPrime() {
primes[0] = 0;
memset(vis, 0, sizeof(vis));
for (int i = 2; i < maxl; i++) {
if (!vis[i])
primes[++primes[0]] = i;
for (int j = 1; j <= primes[0] && primes[j]*i < maxl; j++) {
vis[primes[j]*i] = 1;
if (i % primes[j] == 0)
break;
}
}
}
inline void prework()
{
scanf("%d%lld",&n,&mod);
mp[0] = 0;
long long temp = mod;
for (int i = 1; i <= primes[0] && temp > 1; i++) {
if (temp%primes[i] == 0) {
mp[++mp[0]] = primes[i];
while (temp%primes[i] == 0)
temp /= primes[i];
}
}
if (temp > 1)
mp[++mp[0]] = temp;
memset(cnt, 0, sizeof(cnt));
for(int i=1;i<=mp[0];i++)
p[i].clear(),p[i].push_back(1ll);
}
void extgcd(int a, int b, long long &d, long long &x, long long &y){
if(!b){ d=a; x=1; y=0;}
else{ extgcd(b,a%b,d,y,x); y-=x*(a/b); }
}
long long inverse(long long a,long long n){
long long d,x,y;
extgcd(a,n,d,x,y);
return d==1?(x+n)%n:-1;
}
inline void mainwork()
{
int temp, d;
long long sum, x=1;
for(int i=1;i<=n;i++)
{
scanf("%s",s);
if(s[0]=='M')
{
scanf("%d",&d);
a[i]=d;
temp = d;
sum = 1;
for (int j = 1; j <= mp[0]; j++) {
while (temp % mp[j] == 0) {
cnt[j]++;
if(p[j].size()<=cnt[j])
{
int l=p[j].size();
p[j].push_back(p[j][l-1]*mp[j]%mod);
}
temp /= mp[j];
}
sum = (sum * p[j][cnt[j]]) % mod;
}
x=(1ll*temp*x)%mod;
printf("%lld\n",(x*sum) % mod);
}
else
{
a[i] = 1;
scanf("%d",&d);
d = a[d];
temp = d;
sum = 1;
for (int j = 1; j <= mp[0]; j++) {
while (temp % mp[j] == 0) {
cnt[j]--;
temp /= mp[j];
}
sum = (sum * p[j][cnt[j]]) % mod;
}
x=(x * inverse(temp, mod))%mod;
printf("%lld\n",(x*sum) % mod);
}
}
}
int main()
{
int t;
getPrime();
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
prework();
mainwork();
}
return 0;
}
#include<cstdio>
#include<cstring>
#define maxl 100010
int n,mod;
int a[maxl];
struct node
{
int l,r,num;
}tree[maxl<<2];
char s[2];
inline void build(int k,int l,int r)
{
tree[k].l=l;tree[k].r=r;
if(l==r)
{
tree[k].num=1;
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);build(k<<1|1,mid+1,r);
tree[k].num=1;
}
inline void prework()
{
scanf("%d%d",&n,&mod);
build(1,1,n);
}
inline void add(int k,int l,int d)
{
int mid=(tree[k].l+tree[k].r)>>1;
if(tree[k].l==tree[k].r)
{
tree[k].num=d;
return;
}
if(l<=mid)
add(k<<1,l,d);
else
add(k<<1|1,l,d);
tree[k].num=1ll*tree[k<<1].num*tree[k<<1|1].num%mod;
}
inline void mainwork()
{
int d;
for(int i=1;i<=n;i++)
{
scanf("%s%d",s,&d);
if(s[0]=='M')
add(1,i,d);
else
add(1,d,1);
printf("%d\n",tree[1].num);
}
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
prework();
mainwork();
//print();
}
return 0;
}