(2018 Multi-University Training Contest 2)Problem G - Naive Operations
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6315
题目大意:告诉你a,b两个数组,a数组初始化为0,b数组告诉你长度和具体值,接下来有q次操作,add操作是从向区间[l,r]加1,query操作是求区[l,r]的ai/bi的总和。
解题思路:维护一个mn,表示这个区间里的a最少加几次才能有新的贡献。比如1最多对总和造成q的贡献,2最多q/2,q/3,q/4,一直到q/n。最少要加min(b[i]-a[i]%b[i])次才能有新的贡献,如果这个区间+1之后没有贡献,也就是mn>1,就直接打标记.
AC代码:
1 #include<iostream> 2 using namespace std; 3 #define rep(i,a,n) for(int i=a;i<n;i++) 4 #define clr(a,x) memset(a,x,sizeof(a)) 5 #define pb push_back 6 #define mp make_pair 7 #define inf 0x3f3f3f3f 8 #define lson rt<<1 9 #define rson rt<<1|1 10 #define Lson l,m,lson 11 #define Rson m+1,r,rson 12 typedef long long ll; 13 14 const ll mod= 1e9+7; 15 const int maxn=1e5+7; 16 17 int n; 18 int a[maxn],b[maxn]; 19 char s[10]; 20 21 int lazy[maxn<<2],sum[maxn<<2],mn[maxn<<2]; 22 void pushup(int rt){ 23 sum[rt]=sum[lson]+sum[rson]; 24 mn[rt]=min(mn[lson],mn[rson]); 25 } 26 void pushdown(int rt,int m){ 27 if(lazy[rt]==0){ 28 return; 29 } 30 lazy[lson]+=lazy[rt]; 31 lazy[rson]+=lazy[rt]; 32 mn[lson]-=lazy[rt]; 33 mn[rson]-=lazy[rt]; 34 lazy[rt]=0; 35 } 36 37 void build(int l,int r,int rt){ 38 lazy[rt]=0; 39 sum[rt]=0; 40 if(l==r){ 41 mn[rt]=b[l]; 42 return ; 43 } 44 int m=(l+r)>>1; 45 build(Lson); 46 build(Rson); 47 pushup(rt); 48 } 49 50 void update(int L,int R,int add,int l,int r,int rt){ 51 if(L<=l&&r<=R&&mn[rt]>1){ 52 lazy[rt]++,mn[rt]--; 53 return ; 54 } 55 if(l==r){ 56 sum[rt]++; 57 mn[rt]=b[l]; 58 return ; 59 } 60 pushdown(rt,r-l+1); 61 int m=(l+r)>>1; 62 if(L<=m) update(L,R,add,Lson); 63 if(m<R) update(L,R,add,Rson); 64 pushup(rt); 65 } 66 67 int query(int L,int R,int l,int r,int rt){ 68 if(L<=l&&r<=R){ 69 return sum[rt]; 70 } 71 pushdown(rt,r-l+1); 72 int m=(r+l)>>1,ret=0; 73 if(L<=m) ret+=query(L,R,Lson); 74 if(m<R) ret+=query(L,R,Rson); 75 return ret; 76 } 77 int main(){ 78 int q; 79 while(~scanf("%d%d",&n,&q)){ 80 for(int i=1;i<=n;i++){ 81 scanf("%d",&b[i]); 82 } 83 build(1,n,1); 84 while(q--){ 85 int l,r; 86 scanf("%s %d %d",s,&l,&r); 87 if(s[0]=='a'){ 88 update(l,r,1,1,n,1); 89 }else{ 90 printf("%d\n",query(l,r,1,n,1)); 91 } 92 } 93 } 94 return 0; 95 }