@[QwQ自动机](/space/show?uid=143834) 再加上把build里那个沙雕的p和l写反的错误改掉,代码是这个了
```cpp
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=100005;
struct Segment_tree2{
ll a[N],ans[N<<2],taga[N<<2],tagc[N<<2],n,m,mod;
inline ll lson(ll p){return p<<1;}//左儿子
inline ll rson(ll p){return (p<<1)|1;}//右儿子
inline void push_up(ll p){ans[p]=(ans[lson(p)]+ans[rson(p)])%mod;}//合并子区间信息
inline void build(ll p,ll l,ll r){//建树
if (l==r){ans[p]=a[l];tagc[p]=1,taga[p]=0;return ;}
ll mid=(l+r)>>1;
build(lson(p),l,mid);
build(rson(p),mid+1,r);
push_up(p);
tagc[p]=1,taga[p]=0;
}
inline void push_down(ll p,ll l,ll r){//下传lazy_tag
ll mid=(l+r)>>1;
ans[lson(p)]=(ans[lson(p)]*tagc[p]+(mid-l+1)*taga[p])%p;
tagc[lson(p)]=(tagc[lson(p)]*tagc[p])%mod;
taga[lson(p)]=(taga[lson(p)]*tagc[p]+taga[p])%mod;//左儿子下传
ans[lson(p)]=(ans[lson(p)]*tagc[p]+(r-mid)*taga[p])%p;
tagc[rson(p)]=(tagc[rson(p)]*tagc[p])%mod;
taga[rson(p)]=(taga[rson(p)]*tagc[p]+taga[p])%mod;//右儿子下传
tagc[p]=1,taga[p]=0;
}
inline void change1(ll p,ll l,ll r,ll nl,ll nr,ll k){//区间加,(l,r)为当前访问区间,(nl,nr)为修改区间
if (nl<=l&&nr>=r){ans[p]=(ans[p]+(r-l+1)*k)%mod;taga[p]=(taga[p]+k)%mod;return ;}
if (l>nr||r<nl)return ;
push_down(p,l,r);
ll mid=(l+r)>>1;
change1(lson(p),l,mid,nl,nr,k);
change1(rson(p),mid+1,r,nl,nr,k);
push_up(p);
}
inline void change2(ll p,ll l,ll r,ll nl,ll nr,ll k){//区间乘,(l,r)为当前访问区间,(nl,nr)为修改区间
if (nl<=l&&nr>=r){ans[p]=(ans[p]*k)%mod;tagc[p]=(tagc[p]*k)%mod;taga[p]=(taga[p]*k)%mod;return ;}
if (l>nr||r<nl)return ;
push_down(p,l,r);
ll mid=(l+r)>>1;
change2(lson(p),l,mid,nl,nr,k);
change2(rson(p),mid+1,r,nl,nr,k);
push_up(p);
}
inline ll ask(ll p,ll l,ll r,ll nl,ll nr){//查询,(l,r)为当前访问区间,(nl,nr)为查询区间
if (nl<=l&&nr>=r){return ans[p];}
if (l>nr||r<nl)return 0;
push_down(p,l,r);
ll mid=(l+r)>>1,res=0;
res=(res+ask(lson(p),l,mid,nl,nr))%mod;
res=(res+ask(rson(p),mid+1,r,nl,nr))%mod;
return res;
}
}tree;
int n,m,k,l,r;
int main(){
scanf ("%d%d%d",&n,&m,&tree.mod);
for (int i=1;i<=n;i++)scanf ("%d",&tree.a[i]);
tree.build(1,1,n);
while(m--){
int flag;
scanf ("%d",&flag);
switch(flag){
case 1:scanf ("%d%d%d",&l,&r,&k);tree.change2(1,1,n,l,r,k);break;
case 2:scanf ("%d%d%d",&l,&r,&k);tree.change1(1,1,n,l,r,k);break;
case 3:scanf ("%d%d",&l,&r);printf ("%lld\n",tree.ask(1,1,n,l,r));
}
}
}
```
然而样例还是WA了????
by 引领天下 @ 2019-05-12 17:26:57
@[引领天下](/space/show?uid=39863) 好吧是窝眼瞎 ...
~~最近主席树打多了, 不适应这种没有l和r的线段树~~
by aminoas @ 2019-05-12 17:27:30
@[引领天下](/space/show?uid=39863) 应该是p和l写反的锅 ...
然鹅还是WA ...
问一下, 输出还是0吗?
by aminoas @ 2019-05-12 17:28:51
@[QwQ自动机](/space/show?uid=143834) 不是,是1和空行……
by 引领天下 @ 2019-05-12 17:31:53
@[引领天下](/space/show?uid=39863) 空行?!
by aminoas @ 2019-05-12 17:33:19
@[QwQ自动机](/space/show?uid=143834) 对啊,所以迷
by 引领天下 @ 2019-05-12 17:34:49
@[baoyu](/space/show?uid=93465) QAQ我真不会
by 引领天下 @ 2019-05-12 17:37:20
@[引领天下](/space/show?uid=39863) 试着每操作一次, 就把每个数输一遍?
(就是访问区间一个数本身)
by aminoas @ 2019-05-12 17:39:56
@[引领天下](/space/show?uid=39863)
```
int main(){
scanf ("%d%d%d",&n,&m,&tree.mod);
for (int i=1;i<=n;i++)scanf ("%d",&tree.a[i]);
tree.build(1,1,n);
while(m--){
int flag;
scanf ("%d",&flag);
switch(flag){
case 1:scanf ("%d%d%d",&l,&r,&k);tree.change2(1,1,n,l,r,k);break;
case 2:scanf ("%d%d%d",&l,&r,&k);tree.change1(1,1,n,l,r,k);break;
case 3:scanf ("%d%d",&l,&r);printf ("%lld\n",tree.ask(1,1,n,l,r));
}
for (int i=1;i<=n;i++)printf ("%lld", tree.ask(1,1,n,i,i));
}
}
```
应该可以
by aminoas @ 2019-05-12 17:42:45
(前提是ask函数没有写错)
by aminoas @ 2019-05-12 17:43:20