题目:Sliding Window
大体内容:
题意:从后往前扫描k长的段,输出每段的最小值,最大值
解法:由于时间的原因可以选择线段树(RMQ更佳)
具体分析
线段树维护一个最大值和最小值
查询的时候不同于以往,向下递归不改变段的左右区间(具体见代码)
-
-
-
-
-
-
-
- #include<iostream>
- #include<cstring>
- #include <algorithm>
- #include<cstdlib>
- #include<vector>
- #include<cmath>
- #include<stdlib.h>
- #include<iomanip>
- #include<list>
- #include<deque>
- #include<map>
- #include <stdio.h>
- #include <queue>
-
- #define maxn 4000100+5
-
- #define inf 0x3f3f3f3f
- #define INF 0x3FFFFFFFFFFFFFFFLL
- #define rep(i,n) for(i=0;i<n;i++)
- #define reP(i,n) for(i=1;i<=n;i++)
-
- #define ull unsigned long long
- #define ll long long
- #define LL(x) x<<1
- #define RR(x) x<<1|1
-
- #define cle(a) memset(a,0,sizeof(a))
-
- using namespace std;
- struct node{
- int l,r,mi,ma,val;
- int mid(){
- return (l+r)>>1;
- }
- }tree[maxn];
- void doit(int rt){
- tree[rt].mi=min(tree[LL(rt)].mi,tree[RR(rt)].mi);tree[rt].ma=max(tree[LL(rt)].ma,tree[RR(rt)].ma);
- }
- void build(int rt,int l,int r){
- tree[rt].l=l,tree[rt].r=r;
- if(l==r){
- scanf("%d",&tree[rt].val);tree[rt].mi=tree[rt].ma=tree[rt].val;
-
- return;
- }
- int mid=(l+r)>>1;build(LL(rt),l,mid);build(RR(rt),mid+1,r);
- doit(rt);
- }
- int querymin(int rt,int l,int r){
- if(l<=tree[rt].l&&r>=tree[rt].r){
- return tree[rt].mi;
- }
- int mid=tree[rt].mid();
- int ans1=inf,ans2=inf;
- if(l<=mid)ans1=querymin(LL(rt),l,r);
- if(r>mid)ans2=querymin(RR(rt),l,r);
- return min(ans1,ans2);
- }
- int querymax(int rt,int l,int r){
- if(l<=tree[rt].l&&r>=tree[rt].r){
- return tree[rt].ma;
- }
- int mid=tree[rt].mid();
- int ans1=-1000000000,ans2 =-1000000000;
- if(l<=mid)ans1=querymax(LL(rt),l,r);
- if(r>mid)ans2=querymax(RR(rt),l,r);
- return max(ans1,ans2);
- }
- int main()
- {
- #ifndef ONLINE_JUDGE
- freopen("in.txt","r",stdin);
-
- #endif
- int n,m;
- while(scanf("%d%d",&n,&m)!=EOF){
- int i,j;
- build(1,1,n);
- for(i=1;i<=n-m+1;i++)
- {
- printf("%d ",querymin(1,i,i+m-1));
- }
- printf("\n");
- for(i=1;i<=n-m+1;i++)
- {
- printf("%d ",querymax(1,i,i+m-1));
- }
- printf("\n");
- }
- return 0;
- }
题目:Balanced Lineup
大体内容
题意:给你区间,求此区间最大的差
解法:同上,维护最大最小值
具体分析
同上
-
-
-
-
-
-
- #include<iostream>
- #include<cstring>
- #include <algorithm>
- #include<cstdlib>
- #include<vector>
- #include<cmath>
- #include<stdlib.h>
- #include<iomanip>
- #include<list>
- #include<deque>
- #include<map>
- #include <stdio.h>
- #include <queue>
-
- #define maxn 4000100+5
-
- #define inf 0x3f3f3f3f
- #define INF 0x3FFFFFFFFFFFFFFFLL
- #define rep(i,n) for(i=0;i<n;i++)
- #define reP(i,n) for(i=1;i<=n;i++)
-
- #define ull unsigned long long
- #define ll long long
- #define LL(x) x<<1
- #define RR(x) x<<1|1
-
- #define cle(a) memset(a,0,sizeof(a))
-
- using namespace std;
- struct node{
- int l,r,mi,ma,val;
- int mid(){
- return (l+r)>>1;
- }
- }tree[maxn];
- void doit(int rt){
- tree[rt].mi=min(tree[LL(rt)].mi,tree[RR(rt)].mi);tree[rt].ma=max(tree[LL(rt)].ma,tree[RR(rt)].ma);
- }
- void build(int rt,int l,int r){
- tree[rt].l=l,tree[rt].r=r;
- if(l==r){
- scanf("%d",&tree[rt].val);tree[rt].mi=tree[rt].ma=tree[rt].val;
-
- return;
- }
- int mid=(l+r)>>1;build(LL(rt),l,mid);build(RR(rt),mid+1,r);
- doit(rt);
- }
- int querymin(int rt,int l,int r){
- if(l<=tree[rt].l&&r>=tree[rt].r){
- return tree[rt].mi;
- }
- int mid=tree[rt].mid();
- int ans1=inf,ans2=inf;
- if(l<=mid)ans1=querymin(LL(rt),l,r);
- if(r>mid)ans2=querymin(RR(rt),l,r);
- return min(ans1,ans2);
- }
- int querymax(int rt,int l,int r){
- if(l<=tree[rt].l&&r>=tree[rt].r){
- return tree[rt].ma;
- }
- int mid=tree[rt].mid();
- int ans1=-1000000000,ans2 =-1000000000;
- if(l<=mid)ans1=querymax(LL(rt),l,r);
- if(r>mid)ans2=querymax(RR(rt),l,r);
- return max(ans1,ans2);
- }
- int main()
- {
- #ifndef ONLINE_JUDGE
- freopen("in.txt","r",stdin);
-
- #endif
- int n,m;
- while(scanf("%d%d",&n,&m)!=EOF){
- int i,j;
- build(1,1,n);
- rep(i,m){
- int x,y;scanf("%d%d",&x,&y);
- printf("%d\n",querymax(1,x,y)-querymin(1,x,y));
- }
- }
- return 0;
- }