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

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

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

    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)。

输入

4 4
1 2 3
3 1 4
2 2 3
3 1 4

4 4
1 2 2
1 2 3
1 3 4
3 1 4

输出

3
1

24

备注:

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

Em......一个树状数组+逆元的题目(开始用的线段树一直 MLE 哭了T-T )

#include 
#include 
#define ll long long
#define MAXN 1000100
#define Mod 1000000007

ll tr[MAXN];

void read( ll &x ){
	x = 0;
	char ch = getchar();
	for( ; ch<'0' || ch>'9' ; ch=getchar() );
	for( ; ch>='0' && ch<='9' ; ch=getchar() )
		x = x * 10 + ch - '0';
}

ll quickPow( ll n , ll k ){
	int ans = 1;
	while( k ) {
		if( k&1 )
			ans = ans * n % Mod;
		n = n * n % Mod;
		k >>= 1;
	}
	return ans%Mod;
}

void updata( int n , ll pos , ll val ) {
	while( pos<=n ){
		tr[pos] = tr[pos] * val % Mod;
		pos += pos & -pos;
	}
}

ll query( ll pos ){
	ll ans = 1;
	while( pos>0 ){
		ans = ans * tr[pos] % Mod;
		pos -= pos & -pos; 
	}
	return ans;
}

int main(){
//	freopen( "in.txt","r",stdin );
	int n,m;
	ll op,s,e;
	while( ~scanf( "%d%d",&n,&m ) ){
		for( int i=0 ; i<=n ; i++ )
			tr[i] = 1;
		while( m-- ){
			read( op );
			read( s );
			read( e );
			if( op == 1 ){ 
				updata( n,s,e );
			}else if( op == 2 ){
				e = quickPow( e,Mod-2 );
				updata( n,s,e );
			} else {
				printf( "%lld\n",query( e ) % Mod * quickPow( query( s-1 ),Mod-2 ) % Mod );
			}
		}
	}
}

 

你可能感兴趣的:(赛事训练)