数列(seq)

Time Limit: 1 Sec

Memory Limit: 256 MB

题目连接

http://acm.uestc.edu.cn/#/problem/show/1157

Description

给出一个长度为n的数列A。现有如下两种操作:

修改操作:把数列中第i个数改为x

询问操作:给定一个位置i,问数列中有多少个位置j ( j>i ),满足位置i与位置j间所有的数都不超过Ai与Aj的较大值。

现共有m个操作,请对每个询问操作做出回答。

Input

第一行两个正整数n、m。

随后n行,每行一个正整数Ai。

随后m行,若是修改操作,则以一个大写C开头,随后两个正整数i和x;若是查询操作,则以一个大写Q开头,随后一个正整数i。

Output

每行一个整数,依次对每个询问操作给出回答。

Sample Input

5 3
1
3
2
3
2
Q 1
C 1 3
Q 1

Sample Output

2
4

HINT

对于40%的数据,n、m<=5000

对于100%的数据,n、m<=50000,|Ai|、x<=100000

题意

题解:

简单分析一下,就知道,他是让你求有多少个数在他右边比他小

然后再求一个不递减的序列长度

假设,ans[x]表示以a[x]开头的单调不减序列的长度的话

如果查询的位置是x的话,有y个数在他右边比他小,那么答案就是y+ans[y+1]

--------------------

具体做法的话:

如果不分块的话,根本不会……

右边有多少个比他小的,就用线段树来二分就好了

不递减的序列长度,就用分块来维护就好了

代码:

//qscqesze
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <bitset>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define maxn 200006
#define mod 1000000007
#define eps 1e-9
#define e exp(1.0)
#define PI acos(-1)
#define lowbit(x) (x)&(-x)
const double EP = 1E- ;
int Num;
//const int inf=0x7fffffff;
const ll inf=;
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
//************************************************************************************* int n;
int a[maxn]; struct data{
int l,r,mn;
}tr[maxn*];
void build(int k,int s,int t)
{
tr[k].l=s;tr[k].r=t;
if(s==t){tr[k].mn=a[s];return;}
int mid=(s+t)>>;
build(k<<,s,mid);
build(k<<|,mid+,t);
tr[k].mn=max(tr[k<<].mn,tr[k<<|].mn);
}
int ask(int k,int s,int t)
{
int l=tr[k].l,r=tr[k].r;
if(s==l&&t==r)return tr[k].mn;
int mid=(l+r)>>;
if(t<=mid)return ask(k<<,s,t);
if(s>mid)return ask(k<<|,s,t);
return max(ask(k<<,s,mid),ask(k<<|,mid+,t));
}
void update(int k,int x,int y)
{
int l=tr[k].l,r=tr[k].r;
if(l==r){tr[k].mn=y;return;}
int mid=(l+r)>>;
if(x<=mid)update(k<<,x,y);
if(x>mid)update(k<<|,x,y);
tr[k].mn=max(tr[k<<].mn,tr[k<<|].mn);
} int l[],r[];
int belong[];
int block;
vector<int> Q[];
int ans[maxn];
int num;
int main()
{
n = read();
int q=read();
for(int i=;i<=n;i++)
a[i]=read();
block = sqrt(n);
int num = n/block;
if(n%block)num++;
for(int i=;i<=num;i++)
l[i]=(i-)*block+,r[i]=i*block;
r[num]=n;
for(int i=;i<=n;i++)
belong[i]=(i-)/block+; for(int i=;i<=num;i++)
{
int tmp = ;
for(int j=l[i];j<=r[i];j++)
{
if(a[j]>=tmp)
{
Q[i].push_back(a[j]);
tmp = a[j];
}
}
} build(,,n);
char c[];
while(q--)
{
scanf("%s",c);
if(c[]=='Q')
{
int x=read();
int L = x+ , R = n;
while(L<=R)
{
int mid = (L+R)>>;
if(ask(,x+,mid)<=a[x])
L = mid+;
else
R = mid-;
}
//cout<<l<<endl;
ans[x] = L - x - ;
int x2=ans[x]++x;
int k = belong[x2];
int tmp = a[x2];
int Ans = ;
if(x2!=n+){
for(int i=x2;i<=r[k];i++)
{
if(a[i]>=tmp)
{
Ans++;
tmp = a[i];
}
}
for(int i=k+;i<=num;i++)
{
if(!Q[i].empty())
{
if(tmp>Q[i][Q[i].size()-])
continue;
Ans+=Q[i].end()-lower_bound(Q[i].begin(),Q[i].end(),tmp);
tmp = Q[i][Q[i].size()-];
}
}
}
printf("%d\n",Ans + ans[x]);
}
else
{
int x=read();
int y=read();
a[x]=y;
update(,x,y);
int k = belong[x];
Q[belong[x]].clear();
int tmp = ;
for(int i=l[k];i<=r[k];i++)
{
if(a[i]>=tmp)
{
Q[k].push_back(a[i]);
tmp = a[i];
}
}
}
}
}

CDOJ 1157 数列(seq) 分块+线段树的更多相关文章

  1. CDOJ 1292 卿学姐种花 暴力 分块 线段树

    卿学姐种花 题目连接: http://acm.uestc.edu.cn/#/problem/show/1292 Description 众所周知,在喵哈哈村,有一个温柔善良的卿学姐. 卿学姐喜欢和她一 ...

  2. BZOJ5286 HNOI/AHOI2018转盘(分块/线段树)

    显然最优走法是先一直停在初始位置然后一次性走完一圈.将序列倍长后,相当于找一个长度为n的区间[l,l+n),使其中ti+l+n-1-i的最大值最小.容易发现ti-i>ti+n-(i+n),所以也 ...

  3. [LuoguP1438]无聊的数列(差分+线段树/树状数组)

    \(Link\) \(\color{red}{\mathcal{Description}}\) 给你一个数列,要求支持单点查询\(and\)区间加等差数列. \(\color{red}{\mathca ...

  4. [cogs2638]数列操作ψ(双标记线段树)

    题目大意:给定一个数列a,你需要支持的操作:区间and,区间or,询问区间最大值 解题关键: 1.双标记线段树,注意优先级(超时) 当涉及多重标记时,定义出标记的优先级,修改操作时用优先级高(先下放) ...

  5. BZOJ - 2957 (分块/线段树)

    题目链接 本质是维护斜率递增序列. 用分块的方法就是把序列分成sqrt(n)块,每个块分别用一个vector维护递增序列.查询的时候遍历所有的块,同时维护当前最大斜率,二分找到每个块中比当前最大斜率大 ...

  6. bzoj 1798 [Ahoi2009]Seq 维护序列seq(线段树+传标)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1798 [题意] 给定一个序列,要求提供区间乘/加,以及区间求和的操作 [思路] 线段树 ...

  7. 2018.07.31cogs2964. 数列操作η(线段树)

    传送门 线段树基本操作. 给出一个排列b,有一个初始值都为0的数组a,维护区间加1,区间统计区间∑(ai/bi)" role="presentation" style=& ...

  8. bzoj 维护序列seq(双标记线段树)

    Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 4184  Solved: 1518[Submit][Status][Discus ...

  9. 【BZOJ】1798: [Ahoi2009]Seq 维护序列seq(线段树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1798 之前写了个快速乘..........................20多s...... 还好 ...

随机推荐

  1. NPOI的测试代码

    NPOI\testcases\main\testcases vs10.csproj 需要注意,重新引用一下NPOI类库 需要注意的是,测试项目,使用了NUnit 找到测试项目下的SS文件夹,再定位到U ...

  2. 将非WPF window设为 WPF Window的Owner

    如果WPF Content是寄宿在Win32 窗体或Windows Form中,则在WPF模块中可能不会存在WPF Window(WPF模块的根可能是个UserControl).如果在WPF模块中弹出 ...

  3. windows官方多语言方案

    编写 Win32 多语言用户界面应用程序 Windows 2000 针对全球市场制定了新的增强支持标准,提供了许多国际化功能,例如完全支持 Unicode.预设支持数百种语言以及用于从右向左语言的镜像 ...

  4. android利用WebView实现浏览器的封装

    android提供了封装浏览器的接口,可以让开发者利用自己的view显示网页内容.今天又实现研究了一下,利用WebView显示浏览器内容,还可以利用 WebViewClient显示自己需要的内容. 参 ...

  5. Kryo 为什么比 Hessian 快

    Kryo 是一个快速高效的Java对象图形序列化框架,它原生支持java,且在java的序列化上甚至优于google著名的序列化框架protobuf.由于 protobuf需要编写Schema文件(. ...

  6. 从Decorator,Adapter模式看Java的IO库

    我想任何一本介绍模式的书在讲到Decorator模式的时候不能不提到它的实际应用--在Java/IO库里面的应用,<<Java与模式>>这本书也不例外,有点不一样的是,这本书在 ...

  7. MEF技术

    MEF 是一个使开发人员能够创建“插件式应用程序”的技术,这里的“插件”是指在应用程序部署后开发人员能够通过开发“插件”来扩展应用程序功能.但不同之处是使用MEF框架您在系统设计阶段不需要考虑在应用程 ...

  8. HDU 5699 货物运输 二分判定

    转自:http://blog.csdn.net/jtjy568805874/article/details/51480479 #include <cstdio> #include < ...

  9. LeetCode题解——Longest Palindromic Substring

    题目: 给定一个字符串S,返回S中最长的回文子串.S最长为1000,且最长回文子串是唯一. 解法: ①遍历,对于每个字符,计算以它为中心的回文子串长度(长度为奇数),同时计算以它和右边相邻字符为中心的 ...

  10. NOIP2008 双栈队列

    1.      双栈排序 (twostack.pas/c/cpp) Tom 最近在研究一个有趣的排序问题.如图所示,通过 2 个栈 S1 和 S2,Tom 希望借助 以下 4 种操作实现将输入序列升序 ...