HDU 6315: Naive Operations

Naive Operations

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

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,a_{l+1}...a_r$
2. query l r: query $\sum_{i=l}^r \lfloor a_i / b_i \rfloor$

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 \leq n,q \leq 100000$, $1 \leq l \leq r \leq 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

分析:线段树模板改一改,维护最大值最小值就好了。

#include <iostream>
#include <string>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>
#include <map>
#define range(i,a,b) for(auto i=a;i<=b;++i)
#define LL long long
#define itrange(i,a,b) for(auto i=a;i!=b;++i)
#define rerange(i,a,b) for(auto i=a;i>=b;--i)
#define fill(arr,tmp) memset(arr,tmp,sizeof(arr))
using namespace std;
int b[int(1e5+5)],n,q;
template <class T>
class segtree{
private:
    T *add,*cnt,*minb,*maxa;
    void pushup(int rt){
        minb[rt]=min(minb[rt<<1],minb[rt<<1|1]);
        cnt[rt]=cnt[rt<<1]+cnt[rt<<1|1];
        maxa[rt]=max(maxa[rt<<1],maxa[rt<<1|1]);
    }
    void pushdown(int rt){
        if(add[rt]){
            int v=add[rt];
            add[rt]=0;
            maxa[rt<<1]+=v;
            maxa[rt<<1|1]+=v;
            add[rt<<1]+=v;
            add[rt<<1|1]+=v;
        }
    }
public:
    explicit segtree(int len=int(1e5+5)){
        add=new T[len<<2];fill(add,0);
        cnt=new T[len<<2];fill(cnt,0);
        minb=new T[len<<2];fill(minb,0);
        maxa=new T[len<<2];fill(maxa,0);
    }
    void build(int l,int r,int rt){
        add[rt]=0;
        if(l==r){
            cnt[rt]=maxa[rt]=0;
            minb[rt]=b[l];
            return;
        }
        int m=(l+r)>>1;
        build(l,m,rt<<1);
        build(m+1,r,rt<<1|1);
        pushup(rt);
    }
    void update(int L,int R,T c,int l,int r,int rt){
        if(L<=l&&r<=R){
            maxa[rt]++;
            if(maxa[rt]<minb[rt]){
                ++add[rt];
                return;
            }
            if(l==r&&maxa[rt]>=minb[rt]){
                ++cnt[rt];
                minb[rt]+=b[l];
                return;
            }
        }
        pushdown(rt);
        int m=(l+r)>>1;
        if(L<=m)update(L,R,0,l,m,rt<<1);
        if(m<R)update(L,R,0,m+1,r,rt<<1|1);
        pushup(rt);
    }
    T query(int L,int R,int l,int r,int rt){
        if(L<=l&&r<=R)return cnt[rt];
        int m=(l+r)>>1;
        pushdown(rt);
        T ret=0;
        if(L<=m)ret+=query(L,R,l,m,rt<<1);
        if(m<R)ret+=query(L,R,m+1,r,rt<<1|1);
        return ret;
    }
};
segtree<int>tree;
void init(){}
void solve(){
    while(cin>>n>>q){
        range(i,1,n)scanf("%d",b+i);
        tree.build(1,n,1);
        char op[6];int l,r;
        while(q--){
            scanf("%s%d%d",op,&l,&r);
            if(op[0]==‘a‘)tree.update(l,r,0,1,n,1);
            else printf("%d\n",tree.query(l,r,1,n,1));
        }
    }
}
int main() {
    init();
    solve();
    return 0;
}

原文地址:https://www.cnblogs.com/Rhythm-/p/9375066.html

时间: 2024-10-17 02:31:24

HDU 6315: Naive Operations的相关文章

HDU-DuoXiao第二场hdu 6315 Naive Operations 线段树

hdu 6315 题意:对于一个数列a,初始为0,每个a[ i ]对应一个b[i],只有在这个数字上加了b[i]次后,a[i]才会+1. 有q次操作,一种是个区间加1,一种是查询a的区间和. 思路:线段树,一开始没用lazy,TLE了,然后开始想lazy的标记,这棵线段树的特点是,每个节点维护 :一个区间某个a 要增加1所需个数的最小值,一个区间已加上的mx的最大值标记,还有就是区间和sum. (自己一开始没有想到mx标记,一度想把lazy传回去. (思路差一点就多开节点标记. #include

HDU 4720 :Naive and Silly Muggles

题目:HDU 4720 :Naive and Silly Muggles 题目大意:这题的意思是给出三个点, 然后在给出另一个点,问这个点会不会在覆盖前面三个点的最小的圆里面(包括边界), 在里面最输出danger, 如果任何情况下这个点都不在圆里面,那么就输出safe. 解题思路:三个点最小的覆盖的圆是三角形的外接圆,这样的圆面积一定是最小的. 但是相同面积的圆,所在的位置,覆盖的点会是不一样的.例如垂心关于三条边的对称点,以某个对称点为圆心的圆用之前的半径做圆,如果能够覆盖原来的三个点(点可

hdu 4720 Naive and Silly Muggles(几何)

题目链接:hdu 4720 Naive and Silly Muggles 题目大意:给出三点,找出一个圆,要求面积尽量小,并且三点必须在园内,如果可以找到一个圆,使得说第4个点不在圆内则是安全的. 解题思路:面积最小即三个点外切圆,根据三角形两条边的垂直平分线求出圆心.判断第4个点是否在圆内只要计算距离即可. 然后还要考虑说面积和外切圆相同,但是圆心不同的圆. #include <cstdio> #include <cstring> #include <cmath>

2018 Multi-University Training Contest 2(Naive Operations ) hdu6315

题目连接:Naive Operations 题意,两个数组,一个a[]开始全为0,一个b[]为一个1~n的排列,有两种操作,把[L,R]的a全加1,第二种询问区间[L,R]a[i]/b[i]的和 题解:开一个线段树,最开始为b[i],维护最小值还有位置(有多个最小之时先保存最左边的),每一次更新都对范围的值-1,然后再开个树状数组保存答案,当某个位置 为0时这个位置就可以加1,然后重新置为b[i];,为什么这样不会超时呢(因为总共的操作n=1e5,n/1+n/2+n/2+....n/n,是个调和

HDU6315 Naive Operations(多校第二场1007)(线段树)

Naive Operations Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 502768/502768 K (Java/Others)Total Submission(s): 3636    Accepted Submission(s): 1612 Problem Description In a galaxy far, far away, there are two integer sequence a and b of l

HDU - 6315(2018 Multi-University Training Contest 2) Naive Operations (线段树区间操作)

http://acm.hdu.edu.cn/showproblem.php?pid=6315 题意 a数组初始全为0,b数组为1-n的一个排列.q次操作,一种操作add给a[l...r]加1,另一种操作query查询Σfloor(ai/bi)(i=l...r). 分析 真的是太naive啦,现场时没做出来. 看见区间自然想起线段树,那么这里的关键就是整除问题,只有达到一定数量才会对区间和产生影响. 反过来想,先把a[i]置为b[i],那么每次add时就是-1操作,当a[i]为0时区间和+1,再把

HDU 5938 Four Operations 【贪心】(2016年中国大学生程序设计竞赛(杭州))

Four Operations Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 22    Accepted Submission(s): 12 Problem Description Little Ruins is a studious boy, recently he learned the four operations! Now

HDU 5938 Four Operations 【字符串处理,枚举,把数字字符串变为数值】

Problem Description Little Ruins is a studious boy, recently he learned the four operations! Now he want to use four operations to generate a number, he takes a string which only contains digits ‘1’ - ‘9’, and split it into 5 intervals and add the fo

【2018 Multi-University Training Contest 2 1007】Naive Operations

[链接] 我是链接,点我呀:) [题意] 给你两个数组a,b; b数组是1..n的一个排列. 现在给你两种操作: add l,r将a[l..r]都加上1 query l,r 询问$∑^r_l\frac{ai}{bi} $ 其中a[i]/b[i]是下取整. n<=10^5 [题解] 很优秀的题 我们可以在线段树1中维护所有a[i]/b[i]的值 想一下何时我们才要让线段树1中的值改变? 必然是我们一直加a的值,让a[i]的值超过了b[i] 设让线段树中的值改变操作为操作x 那么操作x最多湖执行多少