#6283. 数列分块入门 7(区间乘法,区间加法,单点询问)
题目链接:https://loj.ac/problem/6283
题目大意:中文题目
具体思路:和线段树的思路相同,注意lazy的下放,对于不完整的区间,我们需要先更新数组a的值,然后再对数组a进行操作。对于完整的操作,我们要注意优先级,如果原来是a*b+c的话,我们要对这个区间乘以e的话,就表示成a*(b*e)+c*e。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 # define ll long long 4 const int maxn = 2e6+100; 5 const int inf = 0x3f3f3f3f; 6 const int mod = 1e4+7; 7 ll l[maxn],r[maxn],belong[maxn]; 8 ll add[maxn],a[maxn],sum[maxn],mul[maxn]; 9 int n; 10 void buildblock() 11 { 12 ll tmp=(ll)sqrt(n); 13 ll tot=n/tmp; 14 if(n%tmp) 15 tot++; 16 for(ll i=1; i<=n; i++) 17 { 18 belong[i]=(i-1)/tmp+1ll; 19 } 20 for(ll i=1; i<=tot; i++) 21 { 22 l[i]=(i-1)*tmp+1ll; 23 r[i]=i*tmp; 24 } 25 r[tot]=n; 26 } 27 void down(int pos) 28 { 29 for(int i=l[pos]; i<=r[pos]; i++) 30 { 31 a[i]=(a[i]*mul[pos]+add[pos]+mod)%mod; 32 } 33 mul[pos]=1; 34 add[pos]=0; 35 } 36 void update1(ll st,ll ed,ll val) 37 { 38 if(belong[st]==belong[ed]) 39 { 40 down(belong[st]); 41 for(ll i=st; i<=ed; i++) 42 a[i]+=val,a[i]%=mod; 43 return ; 44 } 45 down(belong[st]); 46 for(ll i=st; i<=r[belong[st]]; i++) 47 a[i]+=val,a[i]%=mod; 48 down(belong[ed]); 49 for(ll i=l[belong[ed]]; i<=ed; i++) 50 a[i]+=val,a[i]%=mod; 51 for(ll i=belong[st]+1; i<belong[ed]; i++) 52 add[i]+=val,add[i]%=mod; 53 } 54 void update2(ll st,ll ed,ll val) 55 { 56 if(belong[st]==belong[ed]) 57 { 58 down(belong[st]); 59 for(ll i=st; i<=ed; i++) 60 a[i]*=val,a[i]=a[i]%mod; 61 return ; 62 } 63 down(belong[st]); 64 for(ll i=st; i<=r[belong[st]]; i++) 65 a[i]*=val,a[i]%=mod; 66 down(belong[ed]); 67 for(ll i=l[belong[ed]]; i<=ed; i++) 68 a[i]*=val,a[i]%=mod; 69 for(ll i=belong[st]+1; i<belong[ed]; i++) 70 mul[i]*=val,add[i]*=val,mul[i]%=mod,add[i]%=mod; 71 } 72 ll ask(ll pos) 73 { 74 return (a[pos]*mul[belong[pos]]%mod+add[belong[pos]])%mod; 75 } 76 int main() 77 { 78 memset(add,0,sizeof(add)); 79 for(int i=0; i<maxn; i++) 80 mul[i]=1; 81 scanf("%d",&n); 82 for(int i=1; i<=n; i++) 83 { 84 scanf("%lld",&a[i]); 85 } 86 buildblock(); 87 ll op,st,ed; 88 ll val; 89 while(n--) 90 { 91 scanf("%lld %lld %lld %lld",&op,&st,&ed,&val); 92 if(op==0) 93 { 94 update1(st,ed,val); 95 } 96 else if(op==1) 97 { 98 update2(st,ed,val); 99 } 100 else if(op==2) 101 { 102 printf("%lld\n",ask(ed)%mod); 103 } 104 } 105 return 0; 106 }
分类:
(分块)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】博客园携手 AI 驱动开发工具商 Chat2DB 推出联合终身会员
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 依赖注入中的 Captive Dependency
· .NET Core 对象分配(Alloc)底层原理浅谈
· 聊一聊 C#异步 任务延续的三种底层玩法
· 敏捷开发:如何高效开每日站会
· 为什么 .NET8线程池 容易引发线程饥饿
· 终于决定:把自己家的能源管理系统开源了!
· [.NET] 使用客户端缓存提高API性能
· 外部H5唤起常用小程序链接规则整理
· C#实现 Winform 程序在系统托盘显示图标 & 开机自启动
· WPF 怎么利用behavior优雅的给一个Datagrid添加一个全选的功能