問題背景
牆上有n個釘子,編號爲1, 2, ..., n。其中釘子i的橫座標爲i,縱座標初始爲xi。可以進行兩種操作:
0 k v:移動操作。豎直移動釘子k,座標變爲(k, v)。
1 s t v:測試操作。若在高度爲v處放一塊橫座標範圍是[s,t]的水平木板,它將下落到什麼高度?換句話說,求出釘子s, s+1, s+2, …, t的縱座標中,不超過v的最大值。如果這些釘子的高度全部大於v,則木板將落到地上,高度爲0。
注意,在測試操作時,水平木板只是用來測試的“臨時木板”,將在測試後立即被拿走,不會影響到後續測試工作。
輸入格式
第一行包含兩個整數n, m,即釘子的個數和操作的個數(1<=n,m<=105)。以下n行每行一個不超過109的非負整數,即xi。以下 m 行爲各操作 (1 <= k <= n, 1 <= s < t <= n, 1 <= v <= 109 )
輸出格式
按照輸入的順序,對於每個測試操作輸出一個整數,即該測試水平木板的最後高度。
樣例輸入
5 4
1
3
5
7
9
1 2 4 6
0 3 10
1 3 5 7
1 3 5 5
樣例輸出
5
7
0
他人解法:
#include<iostream>
#include<map>
#include<cstdlib>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
int a[m][4],h;
map<int,int> mp;
for(int i=0;i<n;++i)
{
cin>>h;
mp[i]=h;
}
int s,t;
for(int i=0;i<m;++i)
{
int k;
cin>>a[i][0];
if(a[i][0]==0) k=3;
else k=4;
for(int j=1;j<k;++j)
cin>>a[i][j];
}
for(int i=0;i<m;++i)
{
if(a[i][0]==1)
{
h=a[i][3];
s=a[i][1];
t=a[i][2];
int count=0;
for(int i=s-1;i<=t-1;++i)
if(mp[i]>h) ++count;
if(count==t-s+1) { cout<<0<<endl; continue; }
int max=0;
for(int i=s-1;i<=t-1;++i)
if(mp[i]<=h && mp[i]>max) max=mp[i];
cout<<max<<endl;
}
else
{
s=a[i][1];
h=a[i][2];
mp[s-1]=h;
}
}
return 0;
}
本人解法:
#include<stdio.h>
int main()
{
int n,m,i,j,t,k;long a[100001],x,y,z;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
while(m--)
{
scanf("%d",&t);
if(t==1)
{
scanf("%d%d%ld",&x,&y,&z);
k=x;
while(a[k]<=z&&k<=y)
k++;
if(k==x)
printf("0");
else
printf("%ld",a[k-1]);
printf("/n");
}
else
{
scanf("%d%ld",&x,&y);
if(a[x]>y)
{
j=x;
while(j>=2&&a[j-1]>y)
a[j--]=a[j-1];
a[j]=y;
}
else
{
j=x;
while(j<n&&a[j+1]<y)
a[j++]=a[j+1];
a[j]=y;
}
}
}
return 0;
}