1. 程式人生 > >hdu6315(線段樹+lazy操作)

hdu6315(線段樹+lazy操作)

                                         Naive Operations

                           Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 502768/502768 K (Java/Others)
                                                Total Submission(s): 3774    Accepted Submission(s): 1677


 

Problem Description

In a galaxy far, far away, there are two integer sequence a and b of length n.
b is a static permutation of 1 to n. Initially a is filled with zeroes.
There are two kind of operations:
1. add l r: add one for a

l,al+1...ar
2. query l r: query ∑ri=lai/bi

Input

There are multiple test cases, please read till the end of input file.
For each test case, in the first line, two integers n,q, representing the length of a,b and the number of queries.
In the second line, n integers separated by spaces, representing permutation b.
In the following q lines, each line is either in the form 'add l r' or 'query l r', representing an operation.
1≤n

,q≤100000, 1≤lrn, there're no more than 5 test cases.

Output

Output the answer for each 'query', each one line.

Sample Input

5 12 1 5 2 4 3 add 1 4 query 1 4 add 2 5 query 2 5 add 3 5 query 1 5 add 2 4 query 1 4 add 2 5 query 2 5 add 2 2 query 1 5

Sample Output

1 1 2 4 4 6

思路:這題的難點在於怎麼處理ai/bi。由於ai是從0開始的,我們可以記錄區間內b的最小值,將區間最小值賦值為b[l],每次執行加操作就相當於b的最小值減一。當b的區間內最小值為1時,將sum++,並將lazy標記清零,區間最小值重新賦值為b[l]。詳見程式碼

程式碼:

#include <cstdio>
#include <algorithm>
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define LL long long
const int maxn = 111111;
LL add[maxn<<2];
LL sum[maxn<<2];
LL Min[maxn<<2];
int b[maxn];
int N , Q;
void PushUp(int rt) {
       sum[rt] = sum[rt<<1] + sum[rt<<1|1];
       Min[rt] = min(Min[rt<<1] ,Min[rt<<1|1]);
}
void PushDown(int rt) {
       if (add[rt]) {
              add[rt<<1] += add[rt];
              add[rt<<1|1] += add[rt];
              Min[rt<<1] += add[rt];
              Min[rt<<1|1] += add[rt];
              add[rt] = 0;
       }
}
void build(int l,int r,int rt) {
       add[rt]=0;
       sum[rt]=0;
	   if (l == r) {
              Min[rt]=b[l];
              return ;
       }
       int m = (l + r) >> 1;
       build(lson);
       build(rson);
       PushUp(rt);
}
void update(int L,int R,int l,int r,int rt) {
       if (L <= l && r <= R && Min[rt]>1) {
              add[rt] --;
              Min[rt] --;
              return ;
       }
       if(Min[rt]==1&&l==r)
       {
       	    sum[rt]++;
       	    Min[rt]=b[l];
       	    add[rt]=0;
       	    return ;
	   }
       PushDown(rt);
       int m = (l + r) >> 1;
       if (L <= m) update(L , R , lson);
       if (m < R) update(L , R , rson);
       PushUp(rt);
}
LL query(int L,int R,int l,int r,int rt) {
       if (L <= l && r <= R) {
              return sum[rt];
       }
       PushDown(rt);
       int m = (l + r) >> 1;
       LL ret = 0;
       if (L <= m) ret += query(L , R , lson);
       if (m < R) ret += query(L , R , rson);
       return ret;
}
int main() {
       while(scanf("%d%d",&N,&Q)!=EOF)
    {  
         for(int i=1;i<=N;i++)
         scanf("%d",&b[i]);
         build(1 , N , 1);
         while (Q --) {
              char op[10];
              int a , b;
              scanf("%s",op);
              if (op[0] == 'q') {
                     scanf("%d%d",&a,&b);
                     printf("%lld\n",query(a , b , 1 , N , 1));
              } 
			  else {
                     scanf("%d%d",&a,&b);
                     update(a , b , 1 , N , 1);
              }
          }
   }
       return 0;
}