分块随笔入门T2

小M的简单题时间限制: 1 Sec  内存限制: 128 MB 提交: -  解决: - [提交][讨论版]

题目描述

小M是某知名高中的学生,有一天,他请他的n个同学吃苹果,同学们排成一行,且手中已经有一些苹果。为了表示他的大方,有时他会给l到r的同学x个苹果,但为了了解分配的情况,有时他会询问l到r的同学中拥有的苹果数小于x的人的个数。现在,小M想让你帮他解决这道简单题。

输入

第一行:两个整数n,m表示n个同学,m组询问。

第二行:n个数,a[1],a[2]...a[n],a[i]表示第i个同学一开始手中的苹果数。(0<=a[i]<=3e4)

第3~m+2行:每行表示一组询问,格式为C l r x表示给l到r的同学x个苹果,或者Q l r x表示询问l到r的同学中拥有的苹果数小于x的人的个数。(1<=l<=r<=n,0<=x<=3e4)

输出格式:

每行一个数,输出l到r的同学中拥有的苹果数小于x的人的个数。

输出

每行一个数,输出l到r的同学中拥有的苹果数小于x的人的个数。

样例输入

5 5 1 6 3 2 3 Q 1 3 3 C 1 2 2 Q 3 4 3 C 2 3 1 Q 2 3 4
5 4 2 3 1 3 4 C 4 5 3 C 1 5 1 C 2 3 2 Q 1 3 4

样例输出

1 1 0
1

分块模版题

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
vector<int>vec[1004];
int n,blo,v[30005],m,bl[30005],lazy[1004];
void reset(int x)
{
    vec[x].clear();

    for(int i=(x-1)*blo+1;i<=min(x*blo,n);i++)
    vec[x].push_back(v[i]);
    sort(vec[x].begin(),vec[x].end());
}
void change(int l,int r,int val)
{
    for(int i=l;i<=min(blo*bl[l],r);i++)
    {
        v[i]+=val;
    }
    reset(bl[l]);
    if(bl[l]!=bl[r])
    {
        for(int i=(bl[r]-1)*blo+1;i<=r;i++)
        v[i]+=val;
        reset(bl[r]);
    }
    for(int i=bl[l]+1;i<=bl[r]-1;i++)
    lazy[i]+=val;
}
int query(int l,int r,int val)
{
    int ans=0;
    for(int i=l;i<=min(r,bl[l]*blo);i++)
    if(v[i]+lazy[bl[l]]<val)ans++;
    if(bl[l]!=bl[r])
    {
        for(int i=blo*(bl[r]-1)+1;i<=r;i++)
        if(v[i]+lazy[bl[r]]<val) ans++;
    }
    for(int i=bl[l]+1;i<=bl[r]-1;i++)
    ans+=lower_bound(vec[i].begin(),vec[i].end(),val-lazy[i])-vec[i].begin();
    return ans;

}
int main()
{
    scanf("%d %d",&n,&m);
    blo=sqrt(n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&v[i]);
        bl[i]=(i-1)/blo+1;
        vec[bl[i]].push_back(v[i]);
    }
    for(int i=1;i<=bl[n];i++)
    sort(vec[i].begin(),vec[i].end());
    char char_[2];
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        scanf("%s %d %d %d",char_,&x,&y,&z);
        if(char_[0]==‘C‘)
        {
            change(x,y,z);
        }else
        {
            printf("%d\n",query(x,y,z));
        }

    }

}
时间: 2025-01-31 06:50:16

分块随笔入门T2的相关文章

分块简单入门

分块简单入门 按 树状数组虽超级快,但是很僵硬,不灵活:线段树虽快,但是却不直观,代码量大:所以,速度较慢但直观形象.代码量小的分块大法不实为线段树的替代品. 网络上关于分块的教程不知道为什么很少,虽然早有hzwer大神的分块九讲,但是还是少了入门级详解教程.此篇将分为三个阶段,保证初学者在有意识地阅读后基本掌握分块. 1.简单的入门题 问题引入 给定长度为N(N<=1e5)的正数数列A,然后输入Q(Q<=1e5)行操作命令,指令形如Q l r,表示统计数列中第l~r个数中的最大值 思路 首先

Chromium网页光栅化过程分析

在前面一篇文章中,我们分析了网页CC Layer Tree同步为CC Pending Layer Tree的过程.同步操作完成后,CC Pending Layer Tree中的每一个Layer都会被划分成一系列的分块,并且每一个分块都会被赋予一个优先级.接下来CC模块会根据优先级对分块进行排序.优先级越高的分块越排在前面,越排在前面的分块就越快得到光栅化.本文接下来就详细分析网页分块的光栅化过程. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注! CC Pe

Luogu P2261 [CQOI2007]余数求和

最近中考放假几天都在怼一道BJOI2018的水题,但卡死在90pts跑不动啊! 然后今天发现终于过了然而Hack的数据全RE了然后就开始找新的题目来找回信心. 然后发现智能推荐里有这道题,然后想了1min才想到CQOI到底是哪里的原来是重庆呵 其实还是一道比较好的除法分块的入门题.动一下脑子就可以做了. 我们先观察一下最基础的式子: \(\sum_{i=1}^n k\ mod\ i\) 然后我们利用取余的基本性质,即\(k\ mod\ i=k-i\lfloor\frac{k}{i}\rfloor

Caffe入门随笔

Caffe入门随笔 分享一下自己入门机器学习的一些资料:(1)课程,最推荐Coursera上的Andrew NG的Machine Learning,最好注册课程,然后跟下来.其次是华盛顿大学的Machine Learning系列课程,一共有6门,包括毕业设计(2)书籍: 机器学习(周志华西瓜书).机器学习实战.统计学习方法(李航).集体智慧编程.数学之美(吴军)(3)微博@余凯_西二旗民工:@老师木:@梁斌penny:@张栋_机器学习:@邓侃:@大数据皮东:@djvu9:@陈天奇怪(4)知乎@贾

WCF入门随笔 (一). 新建一个WCF服务

1. 新建服务 (1). [文件]--[新建项目]--[WCF服务应用程序] (2). 将默认生成的IService1.cs和Service1.svc文件删除掉 (3). 添加自定义的WCF[服务文件]Math.svc,此时vs2012会自动生成WCF接口文件IMath.cs,我们在IMath中定义WCF方法Add,在Math.svc.cs对该接口的方法进行实现. IMath.cs文件 1 namespace WCFService 2 { 3 [ServiceContract] 4 public

分块入门题

分块入门题-(摘自黄学长的blog) 给出一个长为n的数列,以及n个操作,操作涉及区间加法,询问区间内小于某个值x的前驱(比其小的最大元素). n<=100000其实是为了区分暴力和一些常数较大的写法. 接着第二题的解法,其实只要把块内查询的二分稍作修改即可. 不过这题其实想表达:可以在块内维护其它结构使其更具有拓展性,比如放一个 set ,这样如果还有插入.删除元素的操作,会更加的方便. 分块的调试检测技巧: 可以生成一些大数据,然后用两份分块大小不同的代码来对拍,还可以根据运行时间尝试调整分

Spring学习随笔(2):Eclipse下Spring环境配置+入门项目

1 准备工作 (按需下载) Eclipse 下载:http://www.eclipse.org/downloads/eclipse-packages/ : Spring 下载:http://repo.spring.io/libs-release-local/org/springframework/spring/  版本自选: Spring aop另需的3个包:http://download.csdn.net/download/lk_lxn/6397895 2 Spring IDE help->E

loj6277 数列分块入门题1

裸题分块. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int a[100005],b[10005],n,m,t1,t2,t3,t4,sq; 5 6 int main(){ 7 ios::sync_with_stdio(false); 8 cin>>n; 9 sq=(int)sqrt(n); 10 for(int i=1;i<=n;i++) cin>>a[i]; 11 for(int i=1;i<

loj 6278 6279 数列分块入门 2 3

参考:「分块」数列分块入门1 – 9 by hzwer 2 Description 给出一个长为\(n\)的数列,以及\(n\)个操作,操作涉及区间加法,询问区间内小于某个值\(x\)的元素个数. 思路 每个块内保持升序排列. 则块外暴力统计,块内二分查找分界点. 一些注意点,如: 要记录下标: 块外暴力修改完之后需要再排序: 在块内二分查找的值是\(c-tag[i]\)而非\(c\). Code #include <bits/stdc++.h> #define maxn 50010 #def