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数组为0,给你一个全排列的b数组,q次询问add x y为a数组区间x y增加1,query x y查询a数组整除b数组对应下标的和

题解

区间操作很容易想到线段树

初始每个叶子节点赋值为b[i],维护一个区间最小值min,和区间和sum

对于每个add,区间[X,Y]最小值减1,如果当前区间最小值=1,就继续往下更新,如果更新到叶子节点并且min=1,sum+1

对于每个query,查询区间[X,Y]sum,如果区间min=0,再去暴力更新区间(可以知道一共q次询问,q/1+q/2+q/3+....q/n为调和级数,复杂度O(logn))

总复杂度O(nlog^2 n)

代码

 #include<bits/stdc++.h>
using namespace std; const int N=1e5+; int a[N<<],lazy[N<<],b[N],sum[N<<];
int n;
void PushUp(int rt)
{
a[rt]=min(a[rt<<],a[rt<<|]);
sum[rt]=sum[rt<<]+sum[rt<<|];
}
void PushDown(int rt)
{
if(lazy[rt]==)return;
lazy[rt<<]+=lazy[rt];
lazy[rt<<|]+=lazy[rt];
a[rt<<]-=lazy[rt];
a[rt<<|]-=lazy[rt];
lazy[rt]=;
}
void Build(int l,int r,int rt)
{
lazy[rt]=;sum[rt]=;
if(l==r)
{
a[rt]=b[l];
return;
}
int mid=(l+r)>>;
Build(l,mid,rt<<);
Build(mid+,r,rt<<|);
PushUp(rt);
}
void Update(int L,int R,int l,int r,int rt)
{
if(a[rt]>&&L<=l&&r<=R)
{
lazy[rt]++;
a[rt]--;
return;
}
if(a[rt]==&&l==r)
{
sum[rt]++;
lazy[rt]=;
a[rt]=b[l];
return;
}
int mid=(l+r)>>;
PushDown(rt);
if(L<=mid)Update(L,R,l,mid,rt<<);
if(R>mid)Update(L,R,mid+,r,rt<<|);
PushUp(rt);
}
int Query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)return sum[rt];
if(a[rt]==)Update(L,R,,n,);
int mid=(l+r)>>,ans=;
PushDown(rt);
if(L<=mid)ans+=Query(L,R,l,mid,rt<<);
if(R>mid)ans+=Query(L,R,mid+,r,rt<<|);
PushUp(rt);
return ans;
}
int main()
{
int q,x,y;
char op[];
while(scanf("%d%d",&n,&q)!=EOF)
{
for(int i=;i<=n;i++)
scanf("%d",&b[i]);
Build(,n,);
for(int i=;i<q;i++)
{
scanf("%s%d%d",op,&x,&y);
if(op[]=='a')
Update(x,y,,n,);
else
printf("%d\n",Query(x,y,,n,));
}
}
return ;
}

HDU 6315 Naive Operations(线段树区间整除区间)的更多相关文章

  1. 杭电多校第二场 hdu 6315 Naive Operations 线段树变形

    Naive Operations Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 502768/502768 K (Java/Other ...

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

    hdu 6315 题意:对于一个数列a,初始为0,每个a[ i ]对应一个b[i],只有在这个数字上加了b[i]次后,a[i]才会+1. 有q次操作,一种是个区间加1,一种是查询a的区间和. 思路:线 ...

  3. HDU - 6315 Naive Operations (线段树+思维) 2018 Multi-University Training Contest 2

    题意:数量为N的序列a和b,a初始全为0,b为给定的1-N的排列.有两种操作:1.将a序列区间[L,R]中的数全部+1:2.查询区间[L,R]中的 ∑⌊ai/bi⌋(向下取整) 分析:对于一个位置i, ...

  4. HDU 6315 Naive Operations(线段树+复杂度均摊)

    发现每次区间加只能加1,最多全局加\(n\)次,这样的话,最后的答案是调和级数为\(nlogn\),我们每当答案加1的时候就单点加,最多加\(nlogn\)次,复杂度可以得当保证. 然后问题就是怎么判 ...

  5. HDU 6315.Naive Operations-线段树(两棵树合并)(区间单点更新、区间最值、区间求和)+思维 (2018 Multi-University Training Contest 2 1007)

    6315.Naive Operations 题意很好理解,但是因为区间求和求的是向下取整的a[i]/b[i],所以直接分数更新区间是不对的,所以反过来直接当a[i]==b[i]的时候,线段树对应的位置 ...

  6. hdu 6315 Naive Operations (2018 Multi-University Training Contest 2 1007)

    Naive Operations Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 502768/502768 K (Java/Other ...

  7. HDU 3577Fast Arrangement(线段树模板之区间增减更新 区间求和查询)

    Fast Arrangement Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  8. 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,另一种操 ...

  9. HDU 6315 Naive Operations(线段树+区间维护)多校题解

    题意:a数组初始全为0,b数组题目给你,有两种操作: 思路:dls的思路很妙啊,我们可以将a初始化为b,加一操作改为减一,然后我们维护一个最小值,一旦最小值为0,说明至少有一个ai > bi,那 ...

随机推荐

  1. DirectShow设置采集帧率码率YUV<转>

    // 设置参数,p1=宽,p2=高,p3=帧率 AM_MEDIA_TYPE *p = NULL; IAMStreamConfig *pSC = NULL; pCGB2->FindInterfac ...

  2. javascript _ajax 原理 初级

    1.1使用php 方式获取时间:写一个time.php文件,保存在test 文件夹中 <!DOCTYPE html> <html lang="en"> &l ...

  3. c中计时函数 clock()

    #include<time.h> int main() { // ... .. // .... printf("Time used = %.2lf\n",(double ...

  4. 使用mysqlbinlog恢复指定表

    从整库备份的sql文件中导出某个表的sql语句时,vim查找到表的第一条INSERT语句后,按上下换行键计数INSERT语句的条数,然后按n yy复制,退出vim后,再新建一个文件,按p粘贴刚才的n条 ...

  5. C#可变参数params

    using System.Collections; using System.Collections.Generic; using UnityEngine; public class TestPara ...

  6. Haskell语言练习

    Monad inc n = Just (n + 1) add1 n = [n + 1] main = do print $ Nothing >> (Just 0) -- Nothing p ...

  7. Extjs实现Grid表格显示【一】

    Ext.onReady(function(){ // Ext.Msg.alert("提示","hello world!! "); var stu =new Ex ...

  8. windows下如何查看端口,关闭端口,开启端口

    如何查看端口 在Windows 2000/XP/Server 2003中要查看端口,可以使用NETSTAT命令: “开始">"运行”>“cmd”,打开命令提示符窗口.在 ...

  9. [PHP]基于角色的访问控制RBAC

    ---------------------------------------------------------------------------------------------------- ...

  10. 【deep learning】斯坦福CS231n—深度学习与计算机视觉(资料汇总)

    官网 链接:CS231n: Convolutional Neural Networks for Visual Recognition Notes: 链接:http://cs231n.github.io ...