题目数据范围有问题吧。。。

P3373 【模板】线段树 2

。。。。线段树要开4倍的空间,按理来说你这还是过不了
by Chloris @ 2018-07-09 12:09:01


@[Quanta](/space/show?uid=82722)
by Chloris @ 2018-07-09 12:09:10


我说的是原数组 线段树的我开了4 倍了
by everdream @ 2018-07-09 12:16:47


也就是4*137500
by everdream @ 2018-07-09 12:17:33


那个。。。 我想知道线段树的数组为什么要开得4倍空间还大
by everdream @ 2018-07-09 12:41:54


按我的写法要开6倍 求daolao指教 ~~~cpp #include<iostream> #include<cstdio> #define maxn 100005 using namespace std; typedef long long LL; LL n,m,p,a[maxn],s[maxn*6],add[maxn*6],mul[maxn*6]; inline LL read() { LL ret=0;char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9') ret=(ret<<1)+(ret<<3)+(ch^48),ch=getchar(); return ret; } inline void pushup(int root){s[root]=(s[root<<1]+s[root<<1|1])%p;} inline void build(int L,int R,int root) { mul[root]=1; if (L==R){s[root]=a[L];return;} int mid=(R-L>>1)+L; build(L,mid,root<<1); build(mid+1,R,root<<1|1); pushup(root); } inline void pushdown_add(int root,LL a,LL b) { if (!add[root]) return; add[root<<1]=(add[root<<1]+add[root])%p; add[root<<1|1]=(add[root<<1|1]+add[root])%p; s[root<<1]=(s[root<<1]+add[root]*a%p)%p; s[root<<1|1]=(s[root<<1|1]+add[root]*b%p)%p; add[root]=0; } inline void pushdown_mul(int root) { if (mul[root]==1) return; mul[root<<1]=mul[root<<1]*mul[root]%p; mul[root<<1|1]=mul[root<<1|1]*mul[root]%p; add[root<<1]=add[root<<1]*mul[root]%p; add[root<<1|1]=add[root<<1|1]*mul[root]%p; s[root<<1]=s[root<<1]*mul[root]%p; s[root<<1|1]=s[root<<1|1]*mul[root]%p; mul[root]=1; } void update_add(int L,int R,LL x,int l,int r,int root) { int mid=(r-l>>1)+l; if (L<=l&&r<=R) { pushdown_mul(root); pushdown_add(root,mid-l+1,r-mid); add[root]=(add[root]+x)%p; s[root]=(s[root]+(r-l+1)*x%p)%p; return; } pushdown_mul(root); pushdown_add(root,mid-l+1,r-mid); if (L<=mid) update_add(L,R,x,l,mid,root<<1); if (mid<R) update_add(L,R,x,mid+1,r,root<<1|1); pushup(root); } void update_mul(int L,int R,LL x,int l,int r,int root) { int mid=(r-l>>1)+l; if (L<=l&&r<=R) { pushdown_mul(root); pushdown_add(root,mid-l+1,r-mid); mul[root]=mul[root]*x%p; s[root]=s[root]*x%p; return; } pushdown_mul(root); pushdown_add(root,mid-l+1,r-mid); if (L<=mid) update_mul(L,R,x,l,mid,root<<1); if (mid<R) update_mul(L,R,x,mid+1,r,root<<1|1); pushup(root); } LL query(int L,int R,int l,int r,int root) { if (L<=l&&r<=R) return s[root]%p; int mid=(r-l>>1)+l;LL tot=0; pushdown_mul(root); pushdown_add(root,mid-l+1,r-mid); if (L<=mid) tot=query(L,R,l,mid,root<<1); if (mid<R) tot+=query(L,R,mid+1,r,root<<1|1); return tot%p; } int main() { scanf("%lld%lld%lld",&n,&m,&p); for (int i=1;i<=n;i++) a[i]=read()%p; build(1,n,1); while (m--) { LL flg=read(),L=read(),R=read(); switch(flg) { case 1:{LL x=read();update_mul(L,R,x,1,n,1);break;} case 2:{LL x=read();update_add(L,R,x,1,n,1);break;} case 3:{printf("%lld\n",query(L,R,1,n,1));break;} } } return 0; } ~~~
by everdream @ 2018-07-09 12:49:24


@[Quanta](/space/show?uid=82722) 这个问题很明显啊 满二叉树是$2n+1$ 但恶心出题人是不会给你满二叉树的 所以多算一层,≈$4n$
by 初日辉煌 @ 2018-07-15 22:26:01


|