题目链接: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: ",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 ",ans); 169 } 170 } 171 putchar(' '); 172 } 173 return 0; 174 }