链接: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 <stdio.h>
#include <string.h>
#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 );
}
}
}
}