牛客小白月賽6 F 發電
阿新 • • 發佈:2018-08-19
維護 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]的發電機的效率的乘積。示例1由於輸出過大,你需要對輸出結果模1000000007(1e9+7)。輸入
復制4 4 1 2 3 3 1 4 2 2 3 3 1 4輸出
復制3 1說明
操作1之後,每臺發電機效率:1 3 1 1示例2
操作3之後,每臺發電機效率:1 1 1 1輸入
復制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 發電