码迷,mamicode.com
首页 > 其他好文 > 详细

kb-07线段树--11--区间多重该值多种查询

时间:2015-06-01 00:45:27      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:

  1 /*
  2    lazy思想的运用,因为查询多种,如果全记录就太繁了,lazy就是如果该区间的每一个叶子的状态都相同就不用深入下去该值,只要暂时标记下,查询的时候也不用下去,直接计算;
  3 
  4  */
  5 #include<iostream>
  6 #include<cstdio>
  7 #include<cstring>
  8 #include<algorithm>
  9 #define MAX_N 100005
 10 #define mod 10007
 11 #define ll long long
 12 using namespace std;
 13 struct tree
 14 {
 15     ll l,r,la[4];
 16     ll same,s;//s表示该区间的值都是s;
 17 }tr[MAX_N*4];
 18 ll ans=0;
 19 void build(int rt,int l,int r)
 20 {
 21     tr[rt].l=l;
 22     tr[rt].r=r;
 23     tr[rt].same=1;
 24     tr[rt].s=0;
 25     memset(tr[rt].la,0,sizeof(tr[rt].la));
 26     tr[rt].la[2]=1;
 27     if(l==r)
 28         return ;
 29     int mid=(l+r)/2;
 30     build(rt<<1,l,mid);
 31     build(rt<<1|1,mid+1,r);
 32 }
 33 void Pushdown(int rt)
 34 {
 35     if(tr[rt].same==1)
 36     {
 37     int L=rt<<1,R=rt<<1|1;
 38     tr[L].la[1]+=tr[rt].la[1];
 39     tr[L].la[2]*=tr[rt].la[2];
 40     tr[L].la[3]=tr[rt].la[3];
 41     tr[L].s=tr[R].s=tr[rt].s;
 42     tr[R].la[1]+=tr[rt].la[1];
 43     tr[R].la[2]*=tr[rt].la[2];
 44     tr[R].la[3]=tr[rt].la[3];
 45     tr[L].same=tr[R].same=1;
 46     tr[rt].la[1]=0;
 47     tr[rt].la[2]=1;
 48     tr[rt].la[3]=0;
 49     tr[rt].same=0;
 50     }
 51     return;
 52 }
 53 void Update(int rt,int l,int r,int x,int t)
 54 {
 55     if(t==1)
 56     {
 57         if(tr[rt].l==l&&tr[rt].r==r&&tr[rt].same==1)
 58         {
 59             tr[rt].la[1]+=x;//关键;
 60             tr[rt].la[1]%=mod;
 61             tr[rt].s=tr[rt].s+x;
 62             return ;
 63         }
 64     }
 65     else if(t==2)
 66     {
 67         if(tr[rt].l==l&&tr[rt].r==r&&tr[rt].same==1)
 68         {
 69             tr[rt].la[2]*=x;
 70             tr[rt].la[2]%=mod;
 71             tr[rt].s=tr[rt].s*x%mod;
 72             return ;
 73         }
 74     }
 75     else
 76     {
 77         if(tr[rt].l==l&&tr[rt].r==r)
 78         {
 79             tr[rt].la[3]=x;
 80             tr[rt].s=x;
 81             tr[rt].same=1;
 82             return;
 83         }
 84     }
 85     if(tr[rt].same==1)
 86         Pushdown(rt);
 87     int L=rt<<1,R=rt<<1|1;
 88     if(l<=tr[L].r)
 89     {
 90         if(r<=tr[L].r)
 91             Update(L,l,r,x,t);
 92         else
 93             Update(L,l,tr[L].r,x,t);
 94     }
 95     if(r>=tr[R].l)
 96     {
 97         if(l>=tr[R].l)
 98             Update(R,l,r,x,t);
 99         else
100             Update(R,tr[R].l,r,x,t);
101     }
102 }
103 void Query(int rt,int l,int r,int x)
104 {
105     if(tr[rt].l==l&&tr[rt].r==r&&tr[rt].same==1)
106     {
107         ll n=r-l+1,temp=1;
108         for(int i=1;i<=x;i++)
109         {
110             temp*=tr[rt].s%mod;
111             temp%=mod;
112         }
113         ans+=(temp*n%mod)%mod;
114         return ;
115     }
116     if(tr[rt].same==1)
117         Pushdown(rt);
118     int L=rt<<1,R=rt<<1|1;
119     if(l<=tr[L].r)
120     {
121         if(r<=tr[L].r)
122             Query(L,l,r,x);
123         else
124             Query(L,l,tr[L].r,x);
125     }
126     if(r>=tr[R].l)
127     {
128         if(l>=tr[R].l)
129             Query(R,l,r,x);
130         else
131             Query(R,tr[R].l,r,x);
132     }
133 }
134 int main()
135 {
136     int n,m;
137     while(scanf("%d%d",&n,&m)!=EOF&&(n||m))
138     {
139         memset(tr,0,sizeof(tr));
140         build(1,1,n);
141         for(int i=0;i<m;i++)
142         {
143             int x,y,ty,c;
144             scanf("%d%d%d%d",&ty,&x,&y,&c);
145             if(ty==4)
146             {
147                 ans=0;
148                 Query(1,x,y,c);
149                 cout<<ans%mod<<endl;
150             }
151             else
152             {
153                 Update(1,x,y,c,ty);
154             }
155 
156         }
157     }
158     return 0;
159 }

 

kb-07线段树--11--区间多重该值多种查询

标签:

原文地址:http://www.cnblogs.com/by-1075324834/p/4542985.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!