牛客-牛客小白月赛6-F 发电

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/C_13579/article/details/81878899

链接:https://www.nowcoder.com/acm/contest/136/F
来源:牛客网

题目描述 
    HA实验是一个生产、提炼“神力水晶”的秘密军事基地,神力水晶可以让机器的工作效率成倍提升。
    HA实验基地有n台发电机,标号为1-n,每台发电机的发电效率为1。
    为了满足基地的用电需求,HtBest会在某台发电机上镶嵌一个等级为i的神力水晶,该发电机的发电效率是镶嵌神力水晶之前的i倍,一个发电机可以同时镶嵌多个神力水晶。
    但是神力水晶有时还有别的用处,HtBest会拆掉某台发电机之前镶嵌上的一个神力水晶(设等级为i),发电机效率降为拆掉神力水晶前的1/i。
    HtBest有时想知道第l到r台发电机的总发电效率为多少。
输入描述:
第一行有2个正整数n,m,分别表示发电机数量和操作数。
接下来m行,每行有3个正整数,x, y, z。
x=1时,HtBest镶嵌为第y台发电机镶嵌了一个等级为z的神力水晶,
x=2时,HtBest为第y台发电机拆掉了一个等级为z的神力水晶,
x=3时,HtBest想知道[y,z]的发电机效率的乘积。
输出描述:
对于每个x=3的操作,输出一行,表示[y,z]的发电机的效率的乘积。
由于输出过大,你需要对输出结果模1000000007(1e9+7)。

备注:
对于100%的测试数据:
1 ≤ n, m ≤ 1000000
1 ≤ 神力水晶等级 ≤ 100000
数据量较大,注意使用更快的输入输出方式。

思路:树状数组求解区间乘积,对于除法改成乘以其逆元即可

Code :

#include<iostream>
using namespace std;
typedef long long LL;

const int MOD=1e9+7;
const int MAX_N=1000005;
int n,Q;
LL C[MAX_N];

LL Pow(LL a,LL n);
int Lowbit(int x);
void Update(int id,LL x);
LL Query(int id);
int main()
{
	scanf("%d%d",&n,&Q);
	for(int i=1;i<=n;++i)
		C[i]=1;
	int x,y,z;
	while(Q--){
		scanf("%d%d%d",&x,&y,&z);
		if(x==1){
			Update(y,z);
		}else	if(x==2){
			Update(y,Pow(z,MOD-2));
		}else	if(x==3){
			int ans=Query(z)*Pow(Query(y-1),MOD-2)%MOD;
			printf("%d\n",ans);
		}
	}
	
	return 0;
}

LL Pow(LL a,LL n)
{
	LL ans=1;
	while(n){
		if(n&1)	ans=ans*a%MOD;
		n>>=1;
		a=a*a%MOD;
	}
	return ans;
}

int Lowbit(int x)
{
	return x&(-x);
}

void Update(int id,LL x)
{
	while(id<=n){
		C[id]=C[id]*x%MOD;
		id+=Lowbit(id);
	}
}

LL Query(int id)
{
	LL ans=1;
	while(id>0){
		ans=ans*C[id]%MOD;
		id-=Lowbit(id);
	}
	return ans;
}

猜你喜欢

转载自blog.csdn.net/C_13579/article/details/81878899