Remember, Red, hope is good thing, mabye the best of things. And no good thing ever die.——肖申克的救赎
题目链接
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
阿强采摘了一些苹果,并把他们分堆排成了一行,从左往右编号为第 1 … 𝑛 堆,其中第𝑖堆苹果有
a
i
a_i
ai个。
完美主义者阿珍看到这些苹果,觉得他们摆放的非常杂乱。她要求阿强进行如下的操作。
对某堆苹果进行调整:阿强将会将第𝑖堆苹果调整成
b
i
b_i
bi个;
对阿珍询问做出答复:其中每次询问表示为[𝑙, 𝑟],表示询问第𝑙堆到第𝑟堆之间的苹果数量是否满足
a
l
≤
a
l
+
1
≤
…
≤
a
r
−
1
≤
a
r
a_l\le a_{l+1} \le …\le a_{r-1} \le a_r
al≤al+1≤…≤ar−1≤ar,如果满足则称为完美。
输入描述
第一行两个整数n,q(1<=n,q<=3*10^5),表示苹果的堆数和操作的个数;
第二行n个整数表示
a
i
a_i
ai。
以下𝑞行,每行3个整数,第一个整数为opt;
若opt = 1,之后两个整数
i
,
b
i
i,b_i
i,bi表示将第𝑖堆苹果调整为
b
i
b_i
bi个;
若opt = 2,之后两个整数𝑙, 𝑟,表示对[𝑙, 𝑟]之间的苹果堆进行询问。(1<=
a
i
,
b
i
a_i,b_i
ai,bi<=10^9)
输出描述:
输出一共𝑞行,每行一个 Yes 或者 No,表示每个询问对应区间是否完美。
输入
7 4
1 2 2 4 3 4 5
1 1 4
2 1 7
2 6 7
2 4 7
输出
No
Yes
No
队友A的想法:
先把这些数用a数组存起来,然后再用一个树状数组c表示每一个数对于前一个数是不是非递减,如果这个数大于等于前面的数,就记为0,否则记为-1。
1 | 2 | 2 | 4 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | -1 | 0 | 0 |
这样我们可以用树状数组实现logn的修改和查询,如果l到r是完美区间,则sum(r )-sum(l+1)=0。
但是因为我太菜了,一直WA…
然后队友B突然说这题过了,我们都很震惊,发现居然暴力就能过:D。。。。。
晚上回来终于把这题改过了,说明这个思路是没问题的
树状数组版
#include<bits/stdc++.h>
using namespace std;
long long c[300005];
long long num[300005];
int n;
int lowbit(int x){
return (x&(-x));
}
void update(int i,int val){
while(i<=n){
c[i]+=val;
i+=lowbit(i);
}
}
int sum(long long i){
int ans=0;
while(i>=1){
ans+=c[i];
i-=lowbit(i);
}
return ans;
}
int main(){
int q,i;
cin>>n>>q;
for(i=1;i<=n;i++){
cin>>num[i];
if(num[i]<num[i-1]){//如果一个数小于前一个数,就把它设为-1
update(i,-1);
}
}
for(i=1;i<=q;i++){
int opt;
long long a,b;
cin>>opt>>a>>b;
if(opt==1){
num[a]=b;
//更改一个数,要判断这个数和后面那个数!
if(b>=num[a-1]) {//这个数大于等于前一个数
if(sum(a)-sum(a-1)==-1) update(a,1);
//如果这个数原本小于前面的数,将-1改为0;如果这个数原本大于等于前面的数就不用改
}
else{//这个数小于前一个数
if(sum(a)-sum(a-1)==0) update(a,-1);
//如果这个数原本大于等于前面的数,将0改为-1,;如果这个数原本小于前面的数就不用改
}
if(num[a+1]>=b){//判断这个数的后一个数,同上。
if(sum(a+1)-sum(a)==-1) update(a+1,1);
}
else{
if(sum(a+1)-sum(a)==0) update(a+1,-1);
}
}
else if(opt==2){
int ans=sum(b)-sum(a);//计算a+1到b的区间和
if(ans==0) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}
return 0;
}
暴力版
#include<iostream>
using namespace std;
int main(){
int n,q,l,r,opt;
long long a[300005];
cin>>n>>q;
int i,j;
for(i=1;i<=n;i++){
cin>>a[i];
}
for(i=1;i<=q;i++){
cin>>opt>>l>>r;
if(opt==1)a[l]=r;
else{
for(j=l;j<r;j++){
if(a[j]>a[j+1])break;
}
if(j==r)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}//cout<<a[l]<<" ";
}
return 0;
}
这道题告诉我们如果实在不会要勇敢的写暴力!!说不定就过了!!