指针式线段树 bzoj 1798

来源:互联网 发布:seo常用术语 编辑:程序博客网 时间:2024/05/16 19:40

学习了指针,重写bzoj 1798

数组本质是指针,所以可以buid(tr,1,n)

一个Tree *tr指针,tr[1]指的是这个指针指向的下一个位置,不是开数组的那个tr,所以都改成了root

#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define ll long long#define inf 1e9#define md#define N 100010using namespace std;struct Tree{ll cheng,jia,sum,sz;int l,r;Tree *left,*right;} tr[4*N];int cnt=0,p,a[N];typedef long long Qtype;void add(Tree *root,ll jia,ll cheng){root->cheng=root->cheng*cheng%p;root->jia=(root->jia*cheng+jia)%p;root->sum=(root->sum*cheng+root->sz*jia)%p;}void release(Tree *root){Tree *l=root->left,*r=root->right;ll jia=root->jia,cheng=root->cheng;root->jia=0; root->cheng=1;if (l!=NULL) add(l,jia,cheng);if (r!=NULL) add(r,jia,cheng);}void update(Tree *root){root->sum=0;if (root->left!=NULL) root->sum+=root->left->sum;if (root->right!=NULL) root->sum+=root->right->sum;if (root->sum>=p) root->sum-=p;}void build(Tree *root,int l,int r){root->sz=r-l+1; root->jia=0; root->cheng=1; root->l=l; root->r=r;if (l==r){root->left=root->right=NULL;add(root,a[l],1);return;}int mid=(l+r)>>1;root->left=&tr[++cnt];root->right=&tr[++cnt];build(root->left,l,mid); build(root->right,mid+1,r);update(root);}void modify(Tree *root,int l,int r,int ql,int qr,ll jia,ll cheng){if (ql<=l&&r<=qr){add(root,jia,cheng);return;}release(root);int mid=(l+r)>>1;if (ql<=mid) modify(root->left,l,mid,ql,qr,jia,cheng);if (mid+1<=qr) modify(root->right,mid+1,r,ql,qr,jia,cheng);update(root);}Qtype query(Tree *root,int l,int r,int ql,int qr){if (ql<=l&&r<=qr) return root->sum;release(root);int mid=(l+r)>>1;if (qr<=mid) return query(root->left,l,mid,ql,qr);if (mid+1<=ql) return query(root->right,mid+1,r,ql,qr);return (query(root->left,l,mid,ql,qr)+query(root->right,mid+1,r,ql,qr))%p;}int main(){//freopen("a.in","r",stdin); //freopen("","w",stdout);int n,m;scanf("%d%d",&n,&p);for (int i=1;i<=n;i++) scanf("%d",&a[i]);build(tr,1,n);scanf("%d",&m);for (int i=1;i<=m;i++){int ty,l,r,d;scanf("%d",&ty);if (ty==1){scanf("%d%d%d",&l,&r,&d);modify(tr,1,n,l,r,0,d);}else if (ty==2){scanf("%d%d%d",&l,&r,&d);modify(tr,1,n,l,r,d,1);}else{scanf("%d%d",&l,&r);printf("%lld\n",query(tr,1,n,l,r)%p);}}return 0;}



1 0