【线段树】【BZOJ1798】【AHOI2009】维护序列
还是那个学弟@lher出的丧题之一。
链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798
题意简析:就是题目啊。。。
解题思路:显然是线段树啊。。。根据乘法分配律处理一下区间乘法操作,其他就是简单的区间加法查询,很水吧owo。时间效率\(O(m \lg n) \)。
附AC代码:
#include<stdio.h> #include<iostream> #include<cmath> #include<cstring> #include<string> #include<algorithm> #define ll long long #define mid ((l+r)>>1) #define ls (k<<1) #define rs (k<<1|1) using namespace std; struct zxy{ ll val,mult,add; }tr[300000]; int n,mod,q; inline int in(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } inline void pushdown(int k,int l,int r){ if (tr[k].mult==1&&!tr[k].add) return; int D=(r-l)+1; tr[ls].add=(tr[ls].add*tr[k].mult+tr[k].add)%mod; tr[rs].add=(tr[rs].add*tr[k].mult+tr[k].add)%mod; tr[ls].mult=(tr[ls].mult*tr[k].mult)%mod; tr[rs].mult=(tr[rs].mult*tr[k].mult)%mod; tr[ls].val=(tr[ls].val*tr[k].mult+(D-(D>>1))*tr[k].add)%mod; tr[rs].val=(tr[rs].val*tr[k].mult+(D>>1)*tr[k].add)%mod; tr[k].mult=1,tr[k].add=0; } inline void combine(int k){ tr[k].val=(tr[ls].val+tr[rs].val)%mod; } inline void update(int k,int l,int r,int a,int b,int mult,int add){ if (l>=a&&r<=b){ tr[k].mult=tr[k].mult*mult%mod; tr[k].add=(tr[k].add*mult+add)%mod; tr[k].val=(tr[k].val*mult+(r-l+1)*add)%mod; return; } pushdown(k,l,r); if (a<=mid) update(ls,l,mid,a,b,mult,add); if (b>mid) update(rs,mid+1,r,a,b,mult,add); combine(k); } inline ll query(int k,int l,int r,int a,int b){ if (l==a&&r==b) return tr[k].val%mod; pushdown(k,l,r); if (b<=mid) return query(ls,l,mid,a,b); if (a>mid) return query(rs,mid+1,r,a,b); return (query(ls,l,mid,a,mid)+query(rs,mid+1,r,mid+1,b))%mod; } inline void built(int k,int l,int r){ tr[k].mult=1; tr[k].add=0; if(l==r) { tr[k].val=in(); return; } built(ls,l,mid);built(rs,mid+1,r); combine(k); } int main(){ n=in(),mod=in(); built(1,1,n); q=in(); for (register int i=1; i<=q; ++i){ int typ=in(),l=in(),r=in(); if (typ==2) update(1,1,n,l,r,1,in()); if (typ==1) update(1,1,n,l,r,in(),0); if (typ==3)printf("%lld\n",query(1,1,n,l,r)); } return 0; }
本文由Melacau编写,Melacau代表M星向您问好,如果您不是在我的博客http://www.cnblogs.com/Melacau上看到本文,请您向我联系,email:13960948839@163.com.