杭电多校第二场 1007 HDU-6315 Naive Operations(线段树)

Naive Operations
Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 502768/502768 K (Java/Others)
Total Submission(s): 820    Accepted Submission(s): 302


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 al,al+1...ar
2. query l r: query ∑ri=l⌊ai/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≤l≤r≤n, 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

题目大意:给出两个数组a和b,一开始数组a中的所有元素都为0,数组b为1-n的一个排列。接下来有q次询问,询问有以下两种操作:

1、add l r   令a数组区间[l,r]内的元素加一

2、query l r 查询并输出\sum_{i=l}^{r}\left \lfloor \frac{a_{i}}{b_{i}} \right \rfloor的值

题目思路:本题可以通过建立两棵线段树来解决。第一棵线段树用来维护当前的ai还差多少达到bi的整数倍,这样每次区间更新加一的时候,就将这个区间的值减一,当区间的最小值为0的时候,说明区间内就至少有一个结点达到了bi的倍数,就可以对最终的结果加1,另一棵线段树就是用来维护最终答案,当一个区间在更新后最小值为0时,我们就用一个dfs找到为0的那个结点,再去更新第二棵线段树,再将第一棵线段树对应位置的值重新赋值为bi。查询的时候借助第二棵线段树直接查询即可。

由于b是1-n的排列,那么\sum_{i=1}^{n}\left \lfloor n/b_{i} \right \rfloor就是O(nlogn)的,加上线段树的操作,总体的复杂度就是O(nlog^2n)

具体实现看代码:

#include <bits/stdc++.h>
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lowbit(x) x&-x
#define MP make_pair
#define pb push_back
#define debug(x) cout<<x<<"= "<<x<<endl;
#define FIN freopen("in.txt","r",stdin);
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int>pii;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const ll infll=0x3f3f3f3f3f3f3f3f;
const int MX=1e5+7;

int n,q;
int b[MX];
int MIN[MX<<2],sum[MX<<2],tag[MX<<2];
inline void push_up1(int rt){
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
inline void update1(int p,int l,int r,int rt){
    if(l==r){
        sum[rt]++;
        return;
    }
    int m=(l+r)>>1;
    if(p<=m) update1(p,lson);
    else update1(p,rson);
    push_up1(rt);
}
inline int query(int L,int R,int l,int r,int rt){
    if(L<=l && r<=R) return sum[rt];
    int m=(l+r)>>1,res=0;
    if(L<=m) res+=query(L,R,lson);
    if(R>m) res+=query(L,R,rson);
    return res;
}

inline void push_up2(int rt){
    MIN[rt]=min(MIN[rt<<1],MIN[rt<<1|1]);
}
inline void push_down(int rt){
    if(tag[rt]){
        tag[rt<<1]+=tag[rt];tag[rt<<1|1]+=tag[rt];
        MIN[rt<<1]+=tag[rt];MIN[rt<<1|1]+=tag[rt];
        tag[rt]=0;
    }
}
inline void modity(int l,int r,int rt){
    if(l==r){
        update1(l,1,n,1);
        MIN[rt]=b[l];
        return;
    }
    push_down(rt);
    int m=(l+r)>>1;
    if(!MIN[rt<<1]) modity(lson);
    if(!MIN[rt<<1|1]) modity(rson);
    push_up1(rt);
    push_up2(rt);
}
inline void update2(int L,int R,int l,int r,int rt){
    if(L<=l && r<=R){
        MIN[rt]--;
        tag[rt]--;
        if(!MIN[rt]) modity(l,r,rt);
        return;
    }
    push_down(rt);
    int m=(l+r)>>1;
    if(L<=m) update2(L,R,lson);
    if(R>m) update2(L,R,rson);
    push_up2(rt);
}

inline void build(int l,int r,int rt){
    sum[rt]=tag[rt]=0;
    if(l==r){
        MIN[rt]=b[l];
        return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    push_up1(rt);
    push_up2(rt);
}

int main() {
    //FIN
    while(~scanf("%d%d",&n,&q)) {
        for(int i=1; i<=n; i++) scanf("%d",&b[i]);
        build(1,n,1);
        char op[10];
        int l,r;
        while(q--) {
            scanf("%s%d%d",op,&l,&r);
            if(op[0]=='a')
                update2(l,r,1,n,1);
            else {
                printf("%d\n",query(l,r,1,n,1));
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lee_w_j__/article/details/81212273
今日推荐