1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| #define maxn 1000005 template<typename T> struct segmt{ struct tree{int l,r,lc,rc;T ans,lazy1,lazy2;}tr[2*maxn]; T a[maxn];int tot,n,m;T p; inline int bt(int l,int r) { int pos=++tot; tr[pos].l=l;tr[pos].r=r; tr[pos].lazy1=1;tr[pos].lazy2=0; if(l==r) { tr[pos].lc=tr[pos].rc=-1; tr[pos].ans=a[l]; } else { tr[pos].lc=bt(l,l+r>>1); tr[pos].rc=bt((l+r>>1)+1,r); tr[pos].ans=(tr[tr[pos].lc].ans+tr[tr[pos].rc].ans)%p; } return pos; } void times(int,int,int,int); void add(int,int,int,int); inline void update(int pos) { if(tr[pos].lazy1!=1) { times(tr[pos].lc,tr[tr[pos].lc].l,tr[tr[pos].lc].r,tr[pos].lazy1); times(tr[pos].rc,tr[tr[pos].rc].l,tr[tr[pos].rc].r,tr[pos].lazy1); tr[pos].lazy1=1; } if(tr[pos].lazy2) { add(tr[pos].lc,tr[tr[pos].lc].l,tr[tr[pos].lc].r,tr[pos].lazy2); add(tr[pos].rc,tr[tr[pos].rc].l,tr[tr[pos].rc].r,tr[pos].lazy2); tr[pos].lazy2=0; } tr[pos].ans=(tr[tr[pos].lc].ans+tr[tr[pos].rc].ans)%p; } inline void times(int pos,int l,int r,T x) { if(tr[pos].l==l&&tr[pos].r==r) { tr[pos].lazy1=tr[pos].lazy1*x%p; tr[pos].lazy2=tr[pos].lazy2*x%p; tr[pos].ans=tr[pos].ans*x%p; return; } update(pos); if(r<=tr[tr[pos].lc].r) times(tr[pos].lc,l,r,x); else if(l>=tr[tr[pos].rc].l) times(tr[pos].rc,l,r,x); else { times(tr[pos].lc,l,tr[tr[pos].lc].r,x); times(tr[pos].rc,tr[tr[pos].rc].l,r,x); } tr[pos].ans=(tr[tr[pos].lc].ans+tr[tr[pos].rc].ans)%p; } inline void add(int pos,int l,int r,T x) { if(tr[pos].l==l&&tr[pos].r==r) { tr[pos].lazy2=(tr[pos].lazy2+x)%p; tr[pos].ans=(tr[pos].ans+x*(r-l+1)%p)%p; return; } update(pos); if(r<=tr[tr[pos].lc].r) add(tr[pos].lc,l,r,x); else if(l>=tr[tr[pos].rc].l) add(tr[pos].rc,l,r,x); else { add(tr[pos].lc,l,tr[tr[pos].lc].r,x); add(tr[pos].rc,tr[tr[pos].rc].l,r,x); } tr[pos].ans=(tr[tr[pos].lc].ans+tr[tr[pos].rc].ans)%p; } inline int query(int pos,int l,int r) { if(tr[pos].l==l&&r==tr[pos].r) return tr[pos].ans; update(pos); if(r<=tr[tr[pos].lc].r) return query(tr[pos].lc,l,r); else if(l>=tr[tr[pos].rc].l) return query(tr[pos].rc,l,r); else return (query(tr[pos].lc,l,tr[tr[pos].lc].r)+query(tr[pos].rc,tr[tr[pos].rc].l,r))%p; } };
|