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_lle 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。。。。。
晚上回来终于把这题改过了,说明这个思路是没问题的
树状数组版
#includeusing 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] //如果一个数小于前一个数,就把它设为-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"< 暴力版
#includeusing 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 if(a[j]>a[j+1])break; } if(j==r)cout<<"Yes"< 这道题告诉我们如果实在不会要勇敢的写暴力!!说不定就过了!!



