题目描述
FJ有N(1 <= N <= 10,000)头奶牛,编号为1到N,站成一条直线。每头奶牛自己的身高(正整数,秘密未知),告诉你最高奶牛的身高H及位置I,同时告诉你R(0 <= R <= 10,000)组信息,每组信息由两个数ai,bi组成,表示奶牛ai可以看到奶牛bi,这就意味着奶牛bi的身高至少和奶牛ai的身高一样高,同时奶牛ai到奶牛bi之间的奶牛身高必须低于奶牛ai
现在要你求出每头奶牛最高可能的高度,保证有解。
Input
第1行输入4个空格隔开的整数N,I,H,R
第2到R+1行,每行两个空格隔开的不同的整数A,B(1<=A,B<=N),表示奶牛A能看到奶牛B
Output
第1到N行,每行一个整数表示每只奶牛最高可能的高度。
Sample Input
9 3 5 5
1 3
5 3
4 3
3 7
9 8
Sample Output
5
4
5
3
4
4
5
5
5
解释:如果奶牛A和奶牛B一样高,则可以出现A看到B,B又看到A的情况,如果奶牛A矮于奶牛B,则只可能出现奶牛A看到奶牛B,奶牛B不可能看到奶牛A。
分析
我居然想用LCT做这题
我发现,如果奶牛A与B之间有任意一点高过或与A同高,那么我们就要把奶牛A与B之间的所有奶牛的可能最高高度都要-1,为什么呢?
因为如果其中有一个高度大于等于A的,那么这头奶牛必定曾经作为过至少一次A奶牛,如果它减,那么和它有关的都要减。
那么如果之前没有被覆盖过呢?怎么证有关?
其实直接全部减去都可以,之前没有被覆盖的,那必定大于等于A,如果被覆盖过,那也照减,无论被覆盖过的A是否在当前AB中,都是一样的结果(证明请自己推算数据)
#include <iostream>
#include <cstdio>
#define rep(i,a,b) for (i=a;i<=b;i++)
using namespace std;
int n,I,h,r;
int x,y,w;
int a[50001];
int i,j,k;
int main()
{
scanf("%d%d%d%d",&n,&I,&h,&r);
rep(i,1,n)
a[i]=h;
rep(i,1,r)
{
scanf("%d%d",&x,&y);
w=x;
if (x>y)
{
int t;
t=y;
y=x;
x=t;
}
rep(j,x+1,y-1)
if (a[j]>=a[w])
{
rep(k,x+1,y-1)
a[k]--;
break;
}
}
rep(i,1,n)
printf("%d\n",a[i]);
}