51nod 1349 最大值(单调栈)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1349

题意:

求区间内最大值大于等于k的区间个数。

 

思路:

利用求出对于以a[i]为最大值的区间范围,pre[i]表示左端范围,aft[i]表示右端范围,则区间个数为$(i-pre[i]+1)*(aft[i]-i+1)$。

 1 #include
 2 #include
 3 #include
 4 #include
 5 #include
 6 #include
 7 #include
 8 #include
 9 #include
10 #include<set>
11 using namespace std;
12 typedef long long ll;
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const int maxn = 100000+5;
16 
17 int n;
18 int a[maxn];
19 int sta[maxn];
20 ll ans[maxn];
21 
22 ll pre[maxn],aft[maxn];
23 
24 inline int read()
25 {
26     int x=0,f=1;char ch=getchar();
27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
28     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
29     return x*f;
30 }
31 
32 int main()
33 {
34     //freopen("in.txt","r",stdin);
35     while(~scanf("%d",&n))
36     {
37         for(int i=1;i<=n;i++)  a[i]=read();
38         int top = 0;
39         for(int i=1;i<=n;i++)
40         {
41             while(top && a[sta[top]]<=a[i])  top--;
42             if(top==0)  pre[i]=1;
43             else pre[i]=sta[top]+1;
44             sta[++top]=i;
45         }
46         top=0;
47         for(int i=n;i>=1;i--)
48         {
49             while(top && a[sta[top]]//这儿特别注意一下
50             if(top==0)  aft[i]=n;
51             else aft[i]=sta[top]-1;
52             sta[++top]=i;
53         }
54         memset(ans,0,sizeof(ans));
55         for(int i=1;i<=n;i++)  ans[a[i]]+=(i-pre[i]+1)*(aft[i]-i+1);
56         for(int i=100000;i>=1;i--)  ans[i]+=ans[i+1];
57         int q; q=read();
58         while(q--)
59         {
60             int x; x=read();
61             printf("%lld\n",ans[x]);
62         }
63     }
64     return 0;
65 }

 

转载于:https://www.cnblogs.com/zyb993963526/p/7623765.html

你可能感兴趣的:(51nod 1349 最大值(单调栈))