NEUOJ 1117

View Code
  1 //方法一:用数组模拟队列
2 #include <iostream>
3 #include<stdio.h>
4 #include<stdlib.h>
5 #include<string.h>
6 #include<algorithm>
7 using namespace std;
8 int value[1000010];
9 int Qu[6000010];//单调队列
10 int head, tail;//队列的头和尾
11 void insertBig(int index)//单调减队列,维护最大值
12 {
13 while (tail >= head && value[Qu[tail]] <= value[index])
14 tail--;
15 Qu[++tail] = index;
16 }
17 void insertSmall(int index)//单调曾队列,维护最小值
18 {
19 while (tail >= head && value[Qu[tail]] >= value[index])
20 tail--;
21 Qu[++tail] = index;
22 }
23 int main() {
24 int N, K;
25 while (scanf("%d %d", &N, &K) > 0) {
26 int i;
27 head = 0, tail = -1;
28 for (i = 1; i <= N; i++) {
29 scanf("%d", &value[i]);
30 if (i <= K)
31 insertSmall(i);
32 }
33 printf("%d", value[Qu[head]]);
34 for (i = K + 1; i <= N; i++) {
35 while (tail >= head && Qu[head] < (i - K + 1))
36 head++;
37 insertSmall(i);
38 printf(" %d", value[Qu[head]]);
39 }
40 cout << endl;
41 head = 0, tail = -1;
42 for (i = 1; i <= K; i++)
43 insertBig(i);
44
45 printf("%d", value[Qu[head]]);
46 for (i = K + 1; i <= N; i++) {
47 while (tail >= head && Qu[head] < (i - K + 1))
48 head++;
49 insertBig(i);
50 printf(" %d", value[Qu[head]]);
51 }
52 cout << endl;
53 }
54
55 return 0;
56 }
57
58
59
60
61 //方法二:用priority_queue
62 #include<stdio.h>
63 #include<string.h>
64 #include<iostream>
65 #include<queue>
66 using namespace std;
67 int value[1000001];
68 struct node
69 {
70 int value,index;
71 friend bool operator <(node a,node b)
72 {
73 if(a.value==b.value)return a.index<b.index;
74 return a.value<b.value;
75 }
76 friend bool operator >(node a,node b)
77 {
78 if(a.value==b.value)return a.index>b.index;
79 return a.value>b.value;
80 }
81 };
82 int main(void)
83 {
84 int N,K;
85 while(scanf("%d %d",&N,&K)!=EOF)
86 {
87 int i;
88 priority_queue<node,vector<node>,greater<node> > q;
89 node no;
90 for(i=1;i<=N;i++)
91 {
92 scanf("%d",&value[i]);
93 if(i<=K)
94 {
95 no.value=value[i];
96 no.index=i;
97 q.push(no);
98 }
99 }
100 printf("%d",q.top().value);
101 for(i=K+1;i<=N;i++)
102 {
103 while((!q.empty())&&(q.top().index<(i-K+1)))q.pop();
104 no.value=value[i];
105 no.index=i;
106 q.push(no);
107 printf(" %d",q.top().value);
108 }
109 cout<<endl;
110
111 priority_queue<node,vector<node>,less<node> > Q;
112 for(i=1;i<=K;i++)
113 {
114 no.value=value[i];
115 no.index=i;
116 Q.push(no);
117 }
118 printf("%d",Q.top().value);
119 for(i=K+1;i<=N;i++)
120 {
121 while((!Q.empty())&&(Q.top().index<(i-K+1)))Q.pop();
122 no.value=value[i];
123 no.index=i;
124 Q.push(no);
125 printf(" %d",Q.top().value);
126 }
127 cout<<endl;
128 }
129 }
130
131 //方法三:线段树
132
133 #include<stdio.h>
134 #include<string.h>
135 using namespace std;
136 struct node
137 {
138 int max;
139 int min;
140 int l;
141 int r;
142 };
143 node tree[400000];
144 int value[100005];
145 int maxlis[100005],minlis[100005];
146 int getMAX(int a,int b){return a>b?a:b;}
147 int getMIN(int a,int b){return a<b?a:b;}
148 void build(int l,int r,int root)
149 {
150 tree[root].l=l;
151 tree[root].r=r;
152 if(l==r)
153 {
154 tree[root].max=value[l];
155 tree[root].min=value[l];
156 return ;
157 }
158 int mid=(l+r)>>1;
159 build(l,mid,root*2);
160 build(mid+1,r,root*2+1);
161 tree[root].max=getMAX(tree[2*root].max,tree[root*2+1].max);
162 tree[root].min=getMIN(tree[2*root].min,tree[root*2+1].min);
163 }
164 void find(int l,int r,int &min,int& max,int root)
165 {
166 if(tree[root].l==l&&tree[root].r==r)
167 {
168 min=tree[root].min;
169 max=tree[root].max;
170 return ;
171 }
172 int mid=(tree[root].l+tree[root].r)>>1;
173 if(mid>=r){find(l,r,min,max,root*2);}
174 else if(mid<l)
175 {
176 find(l,r,min,max,root*2+1);
177 }else
178 {
179 int max0=0,min0=0;
180 find(l,mid,min,max,root*2);
181 find(mid+1,r,min0,max0,root*2+1);
182 max=max>max0?max:max0;
183 min=min<min0?min:min0;
184 }
185 }
186 int main(void)
187 {
188 int N,K,i;
189 while(scanf("%d %d",&N,&K)!=EOF)
190 {
191 for(i=1;i<=N;i++)
192 {
193 scanf("%d",&value[i]);
194 }
195 build(1,N,1);
196 int max=0,min=0;
197 for(i=1;i<=N-K+1;i++)
198 {
199 find(i,i+K-1,min,max,1);
200 minlis[i]=min;
201 maxlis[i]=max;
202 }
203 for(i=1;i<=N-K;i++)
204 {
205 printf("%d ",minlis[i]);
206 }
207 printf("%d\n",minlis[N-K+1]);
208 for(i=1;i<=N-K;i++)
209 {
210 printf("%d ",maxlis[i]);
211 }
212 printf("%d\n",maxlis[N-K+1]);
213 }
214 return 0;
215 }

 

转载于:https://www.cnblogs.com/lonelycatcher/archive/2011/12/05/2276658.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值