1. 程式人生 > >牛客小白月賽6 F 發電

牛客小白月賽6 F 發電

維護 max date scanf des spa 復制 best coder

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)。
示例1

輸入

復制
4 4
1 2 3
3 1 4
2 2 3
3 1 4

輸出

復制
3
1

說明

操作1之後,每臺發電機效率:1 3 1 1
操作3之後,每臺發電機效率:1 1 1 1
示例2

輸入

復制
4 4
1 2 2
1 2 3
1 3 4
3 1 4

輸出

復制
24

說明

操作1之後,每臺發電機效率:1 2 1 1
操作2之後,每臺發電機效率:1 6 1 1
操作3之後,每臺發電機效率:1 6 4 1

備註:

對於100%的測試數據:
1 ≤ n, m ≤ 1000000
1 ≤ 神力水晶等級 ≤ 100000
數據量較大,註意使用更快的輸入輸出方式。

思路:

線段樹維護區間乘積即可,註意除法要取逆元。

代碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 1e6+300;
const ll mod = 1e9+7;
struct Node{
    int l,r;
    ll val;
}tree[MAXN*4];

ll qkm(ll a, ll n){
    ll ans =1;
    a=a%mod;
    while(n){
        if(n&1)ans = ans*a%mod;
        a = a*a%mod;
        n>>=1;
    }
    return ans;
}

int a[MAXN];

void build(int l,int r,int k){
    tree[k].l=l;
    tree[k].r=r;
    if(l==r){
        tree[k].val = a[l];
        return;
    }
    int mid = (l+r)/2;
    build(l,mid,2*k);
    build(mid+1,r,2*k+1);
    tree[k].val = (tree[2*k].val*tree[2*k+1].val)%mod;
}

void update(int pos,ll v,int k,int type){
    if(tree[k].l==pos&&tree[k].r==pos){
        if(type==1)   ///鑲嵌水晶
            tree[k].val =tree[k].val*v%mod; 
        else if(type==2) ///拆掉水晶
            tree[k].val = tree[k].val*qkm(v,mod-2)%mod; /// 除法要取逆元
        return;
    }
    int mid = (tree[k].l+tree[k].r)/2;
    if(pos<=mid)update(pos,v,2*k,type);
    else update(pos,v,2*k+1,type);
    tree[k].val= (tree[2*k].val*tree[2*k+1].val)%mod;
}



ll query(int l,int r,int k){
    if(l<=tree[k].l&&tree[k].r<=r){
        return tree[k].val;
    }else{
        int mid = (tree[k].l+tree[k].r)/2;
        if(l>mid) return query(l,r,2*k+1); 
        else if(r<=mid) return query(l,r,2*k);
        else  return query(l,r,2*k)* query(l,r,2*k+1)%mod;
    }
}


int main()
{

    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        a[i] = 1;
    }
    build(1,n,1);

    while(m--){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        if(x==3){
            printf("%lld\n",query(y,z,1));
        }else{
            update(y,(ll)z,1,x);
        }

    }

    return 0;
}

牛客小白月賽6 F 發電