2017.9.13 序列维护 思考记录

来源:互联网 发布:国家顶级域名 编辑:程序博客网 时间:2024/05/21 12:39

终于不对拍1A线段树了、太不容易了

虽然这题挺裸的,省选福利,记住先乘后加的原则就可以搞了

注意位运算和取模的优先级,不要乱了,注意代码的位置问题


码(发现我的线段树非常瘦):

#include<iostream>#include<cstdio>using namespace std;#define zuo o<<1,l,mid#define you o<<1|1,mid+1,r#define lnl long long#define N 100005lnl v[N<<2],jbj[N<<2],cbj[N<<2],a,b,c,op,wc[N],n,m,P,ans;void up(int o){v[o]=(v[o<<1]+v[o<<1|1])%P;}void down(int o,int l,int r){int ll=(o<<1);int rr=(o<<1|1);v[ll]*=cbj[o];v[rr]*=cbj[o];v[ll]+=jbj[o]*(((r+l)>>1)-l+1)%P;v[rr]+=jbj[o]*((r-((r+l)>>1)))%P;v[ll]%=P;v[rr]%=P;jbj[ll]*=cbj[o];jbj[rr]*=cbj[o];        jbj[ll]+=jbj[o];jbj[rr]+=jbj[o];cbj[ll]*=cbj[o];cbj[rr]*=cbj[o];cbj[ll]%=P;cbj[rr]%=P;jbj[ll]%=P;jbj[rr]%=P;cbj[o]=1;jbj[o]=0;}void jian(int o,int l,int r){cbj[o]=1;if(l==r){v[o]=wc[l];return ;}int mid=(l+r)>>1;jian(zuo);jian(you);up(o);}void gai(int o,int l,int r){if(a<=l&&r<=b){  if(op==1)  {  v[o]*=c;v[o]%=P;   cbj[o]*=c;   cbj[o]%=P;   jbj[o]*=c;   jbj[o]%=P;  }if(op==2){v[o]+=c*(r-l+1)%P;v[o]%=P;jbj[o]+=c;jbj[o]%=P;}if(op==3){ans+=v[o];ans%=P;}return;}down(o,l,r);int mid=(l+r)>>1;if(a<=mid)gai(zuo);if(b>mid)gai(you);up(o);}int main(){int i;scanf("%lld%lld",&n,&P);for(i=1;i<=n;i++){scanf("%lld",&wc[i]);}jian(1,1,n); scanf("%lld",&m); for(i=1;i<=m;i++) { scanf("%lld",&op); if(op==1||op==2) { scanf("%lld%lld%lld",&a,&b,&c); gai(1,1,n); } if(op==3) { ans=0; scanf("%lld%lld",&a,&b); gai(1,1,n); printf("%lld\n",ans); } }}