Bnuoj-29359 Deal with numbers 线段树

  题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=29359

  题意:一个数列,有三种操作:

    1.区间[a,b]之间大于零的数整出c。

    2.区间[a,b]之间所有的数减去c。

    3.求区间[a,b]的和。

  只要注意到每个数最多除lgn次,总共除n*lgn次,那么直接对除法进行单点更新就可了,关键要分析好复杂度。。

  1 //STATUS:C++_AC_3020MS_33996KB

  2 #include <functional>

  3 #include <algorithm>

  4 #include <iostream>

  5 //#include <ext/rope>

  6 #include <fstream>

  7 #include <sstream>

  8 #include <iomanip>

  9 #include <numeric>

 10 #include <cstring>

 11 #include <cassert>

 12 #include <cstdio>

 13 #include <string>

 14 #include <vector>

 15 #include <bitset>

 16 #include <queue>

 17 #include <stack>

 18 #include <cmath>

 19 #include <ctime>

 20 #include <list>

 21 #include <set>

 22 #include <map>

 23 using namespace std;

 24 //#pragma comment(linker,"/STACK:102400000,102400000")

 25 //using namespace __gnu_cxx;

 26 //define

 27 #define pii pair<int,int>

 28 #define mem(a,b) memset(a,b,sizeof(a))

 29 #define lson l,mid,rt<<1

 30 #define rson mid+1,r,rt<<1|1

 31 #define PI acos(-1.0)

 32 //typedef

 33 typedef long long LL;

 34 typedef unsigned long long ULL;

 35 //const

 36 const int N=500010;

 37 const int INF=0x3f3f3f3f;

 38 const int MOD=100000,STA=8000010;

 39 const LL LNF=1LL<<60;

 40 const double EPS=1e-8;

 41 const double OO=1e15;

 42 const int dx[4]={-1,0,1,0};

 43 const int dy[4]={0,1,0,-1};

 44 const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

 45 //Daily Use ...

 46 inline int sign(double x){return (x>EPS)-(x<-EPS);}

 47 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}

 48 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}

 49 template<class T> inline T lcm(T a,T b,T d){return a/d*b;}

 50 template<class T> inline T Min(T a,T b){return a<b?a:b;}

 51 template<class T> inline T Max(T a,T b){return a>b?a:b;}

 52 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}

 53 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}

 54 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}

 55 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}

 56 //End

 57 

 58 LL sum[N<<2],miu[N<<2];

 59 int flag[N<<2],num[N];

 60 int T,n,m,a,b,c;

 61 LL ans;

 62 

 63 void pushdown(int l,int r,int rt)

 64 {

 65     if(miu[rt]){

 66         miu[rt<<1]+=miu[rt];

 67         miu[rt<<1|1]+=miu[rt];

 68         sum[rt]+=miu[rt]*(r-l+1);

 69         miu[rt]=0;

 70     }

 71 }

 72 

 73 void pushup(int l,int r,int rt)

 74 {

 75     int mid=(l+r)>>1;

 76     sum[rt]=sum[rt<<1]+(mid-l+1)*miu[rt<<1]

 77         +sum[rt<<1|1]+(r-mid)*miu[rt<<1|1];

 78     flag[rt]=flag[rt<<1]|flag[rt<<1|1];

 79 }

 80 

 81 void build(int l,int r,int rt)

 82 {

 83     miu[rt]=0;

 84     if(l==r){

 85         sum[rt]=num[l];

 86         flag[rt]=num[l]>0;

 87         return;

 88     }

 89     int mid=(l+r)>>1;

 90     build(lson);

 91     build(rson);

 92     sum[rt]=sum[rt<<1]+sum[rt<<1|1];

 93     flag[rt]=flag[rt<<1]|flag[rt<<1|1];

 94 }

 95 

 96 void update1(int l,int r,int rt)

 97 {

 98     if(l==r){

 99         sum[rt]+=miu[rt];

100         miu[rt]=0;

101         sum[rt]=(sum[rt]>0?sum[rt]/=c:sum[rt]);

102         flag[rt]=sum[rt]>0;

103         return;

104     }

105     int mid=(l+r)>>1;

106     pushdown(l,r,rt);

107     if(a<=mid && flag[rt<<1])update1(lson);

108     if(b>mid && flag[rt<<1|1])update1(rson);

109     pushup(l,r,rt);

110 }

111 

112 void update2(int l,int r,int rt)

113 {

114     if(a<=l && r<=b){

115         miu[rt]-=c;

116         return;

117     }

118     int mid=(l+r)>>1;

119     pushdown(l,r,rt);

120     if(a<=mid)update2(lson);

121     if(b>mid)update2(rson);

122     pushup(l,r,rt);

123 }

124 

125 void query(int l,int r,int rt)

126 {

127     if(a<=l && r<=b){

128         ans+=sum[rt]+(r-l+1)*miu[rt];

129         return;

130     }

131     int mid=(l+r)>>1;

132     pushdown(l,r,rt);

133     if(a<=mid)query(lson);

134     if(b>mid)query(rson);

135     pushup(l,r,rt);

136 }

137 

138 int main()

139 {

140  //   freopen("in.txt","r",stdin);

141     int i,j,ca=1;

142     char s[15];

143     scanf("%d",&T);

144     while(T--)

145     {

146         printf("Case %d:\n",ca++);

147         scanf("%d%d",&n,&m);

148         mem(sum,0),mem(miu,0);

149         for(i=1;i<=n;i++){

150             scanf("%d",&num[i]);

151         }

152         build(1,n,1);

153         while(m--){

154             scanf("%s",s);

155             if(s[0]=='D'){

156                 scanf("%d%d%d",&a,&b,&c);

157                 if(c==1)continue;

158                 update1(1,n,1);

159             }

160             else if(s[0]=='M'){

161                 scanf("%d%d%d",&a,&b,&c);

162                 update2(1,n,1);

163             }

164             else {

165                 scanf("%d%d",&a,&b);

166                 ans=0;

167                 query(1,n,1);

168                 printf("%lld\n",ans);

169             }

170         }

171         putchar('\n');

172     }

173     return 0;

174 }

 

你可能感兴趣的:(number)