2020牛客寒假算法基础集训营2 J.求函数 (线段树 推公式 单点修改 区间查询)

https://ac.nowcoder.com/acm/contest/3003/J

题解:

 1 #include<bits/stdc++.h>
 2 typedef long long ll;
 3 using namespace std;
 4 const ll mod = 1e9+7;
 5 const int maxn = 2e5+5;
 6 struct segT{
 7     ll l,r;
 8     ll dat;
 9 }t1[maxn*4],t2[maxn*4]; //两棵线段树 
10 ll k[maxn],b[maxn];
11 ll ans;
12 void build1(ll p,ll l,ll r){
13     t1[p].l = l,t1[p].r = r;
14     if(l == r) { t1[p].dat = k[l]%mod;return;}
15     ll mid = (l+r)/2;
16     build1(p*2,l,mid);
17     build1(p*2+1,mid+1,r);
18     t1[p].dat = ( t1[p*2].dat * t1[p*2+1].dat) %mod ;
19 }
20 void build2(ll p,ll l,ll r){
21     t2[p].l = l,t2[p].r = r;
22     if(l == r) { t2[p].dat = b[l]%mod;return;}
23     ll mid = (l+r)/2;
24     build2(p*2,l,mid);
25     build2(p*2+1,mid+1,r);
26     t2[p].dat =( (t1[p*2+1].dat * t2[p*2].dat)%mod+ t2[p*2+1].dat )%mod ; 
27 }
28 void upd1(ll p,ll L,ll R,ll v){
29     if(t1[p].l == L &&t1[p].r == R ) {t1[p].dat = v;return;}
30     int mid = (t1[p].l + t1[p].r )/2;
31     if (L<=mid) upd1(p*2,L,R,v);
32     else  upd1(p*2+1,L,R,v);
33     t1[p].dat = ( t1[p*2].dat * t1[p*2+1].dat )%mod;
34 }
35 void upd2(ll p,ll L,ll R,ll v){
36     if(t2[p].l == L&&t2[p].r == R ) {t2[p].dat = v;return;}
37     int mid = (t2[p].l + t2[p].r )/2;
38     if(L<=mid) upd2(p*2,L,R,v);
39     else upd2(p*2+1,L,R,v);
40     t2[p].dat =( (t1[p*2+1].dat * t2[p*2].dat)%mod+ t2[p*2+1].dat )%mod ;
41 }
42 
43 void query(ll p,ll l,ll r){
44     if(l<=t2[p].l && r>=t2[p].r ) {
45       ans = (ans*t1[p].dat + t2[p].dat)%mod; //前面的区间*后面区间的t1[p].dat + 后面区间的t2[p].dat   
46       return ;
47     }
48     int mid = (t2[p].l + t2[p].r )/2;
49     if(l<=mid)  query(p*2,l,r);
50     if(r>mid)   query(p*2+1,l,r);
51 }
52 int main()
53 {
54     int n,m;
55     scanf("%d%d",&n,&m);
56     for(int i = 1;i<=n;i++) {
57         scanf("%lld",&k[i]);    
58     }
59     for(int i = 1;i<=n;i++){
60         scanf("%lld",&b[i]);
61     }
62     build1(1,1,n);
63     build2(1,1,n);
64     while(m--){
65         int f;
66         scanf("%d",&f);
67         if(f == 1) {
68             ll pos,tk,tb;
69             scanf("%lld%lld%lld",&pos,&tk,&tb);
70             upd1(1,pos,pos,tk);
71             upd2(1,pos,pos,tb);
72         //    printf("de %d %d\n" ,t1[1].dat,t2[1].dat);
73         }
74         if(f == 2){
75             int l,r;
76             scanf("%lld%lld",&l,&r);
77             ans = 1;
78             query(1,l,r);
79             printf("%lld\n",ans%mod);
80         }
81     }
82     return 0;
83 }

猜你喜欢

转载自www.cnblogs.com/AaronChang/p/12275297.html
今日推荐