问题背景
墙上有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;
}