Special Topics solution monotonous queue

\(T1:[POI2010]PIL-Pilots\)

The meaning of problems: given \ (n, k \) and a length \ (n-\) sequence, selecting the maximum value by not more than the minimum value of the longest \ (K \) of the length of the sequence.

Analysis: maintains two queues monotone, maintain a maximum value, a minimum maintenance, check two subscripts HOL queue whether the difference before each update \ (K \) or less, so that if greater than the lower than standard the head of a small team squad, while the index recorded a minimum current team, behind update for answers.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define ll long long
using namespace std;
inline int read(){
    int x=0,o=1;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')o=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*o;
}
const int N=1e6+5;
int k,n,a[N],q1[N],q2[N];
int main(){
    k=read();n=read();for(int i=1;i<=n;++i)a[i]=read();
    int l1=1,r1=0,l2=1,r2=0,ans=0,last=0;
    for(int i=1;i<=n;++i){
        while(l1<=r1&&a[i]>a[q1[r1]])--r1;q1[++r1]=i;
        while(l2<=r2&&a[i]<a[q2[r2]])--r2;q2[++r2]=i;
        while(a[q1[l1]]-a[q2[l2]]>k){
            if(q1[l1]<q2[l2])last=max(last,q1[l1]),++l1;
            else if(q1[l1]>q2[l2])last=max(last,q2[l2]),++l2;
        }
        ans=max(ans,i-last);
    }
    printf("%d\n",ans);
    return 0;
}

\(T2:Cash\) \(back\)

Los goo

The meaning of problems: you need to put a length \ (n-\) a sequence of any segment, assuming that the length of each segment k, before it is removed (\ lfloor \ frac {k} {m} \ rfloor \) \ a small number, and minimize the rest of the numbers.

Analysis: Suppose we chose a length \ (2M \) section \ ([1, 2M] \) , so to remove this section of minimum \ (MIN1 \) and the second smallest value \ (MIN2 \) , para is the midpoint \ (m \) , these two values are either on the same side of the midpoint, or both sides of the midpoint, respectively.

If both sides of the midpoint values, i.e. \ (MIN1 \) is \ ([1, m] \ ) is the minimum value, \ (MIN2 \) is \ ([m + 1,2m] \ ) minimum value this paragraph we split into two \ ([1, m] \ ) and \ ([m + 1, 2M] \) , then select the minimum value, the contribution of the same is generated.

If the two values on the same side of the mid-point, it is assumed in \ ([1, m] \ ) this period, then the \ ([m + 1,2m] \ ) of this paragraph than the minimum \ (min1, min2 \ ) should be large, so in this case this paragraph we split into two \ ([1, m] \ ) and \ ([m + 1, 2M] \) , then select the minimum value, can be better.

Fully either split this sequence of length \ (m \) segment generates a minimum contribution, or demolition of less of than \ (m \) segment, and a length of less than \ (m \) segment does not occur anyway contribution, it can be seen as a number of length \ (1 \) segments.

A pretreatment can be monotonic queue \ (g [i] \) represents \ ([i-m + 1 , i] \) is the minimum value is then set \ (f [i] \) represents the sequence of consideration of the \ (I \) answer bit is \ (f [i] = min (f [i-1] + a [i], f [im] + sum [i] -sum [im] -g [i]) \) .

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define ll long long
using namespace std;
inline int read(){
    int x=0,o=1;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')o=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*o;
}
const int N=1e5+5;
int n,m,a[N],q[N],g[N];
ll sum[N],f[N];
int main(){
    n=read();m=read();
    for(int i=1;i<=n;++i)a[i]=read(),sum[i]=sum[i-1]+a[i];
    int l=1,r=0;
    for(int i=1;i<=n;++i){
        while(l<=r&&a[i]<=a[q[r]])--r;
        q[++r]=i;
        while(l<=r&&i-q[l]+1>m)++l;
        g[i]=a[q[l]];
    }
    for(int i=1;i<=n;++i){
        f[i]=f[i-1]+a[i];
        if(i-m>=0)f[i]=min(f[i],f[i-m]+sum[i]-sum[i-m]-g[i]);
    }
    printf("%lld\n",f[n]);
    return 0;
}

\ (T3: [NOI2005] \ ) magnificent Waltz

Meaning of the questions:

\ (T4: [USACO12MAR] \ ) pots \ (Flowerpot \)

Los goo

Analysis: pots apparent length is half the answer provided the answer to the current binary \ (MID \) , water droplets from small to large in accordance with the abscissa, respectively, and then seeking to the right end of the abscissa of each point of water droplets, length \ (MID \) most ordinate value interval is included in this section of the water droplets.

Maximum and minimum, respectively, seek to maintain the two queues can be monotonous. If there is a \ (I \) , so \ (MAXN [I] -minn [I]> = m \) , it is a legal answer bipartite .

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define ll long long
using namespace std;
inline int read(){
    int x=0,o=1;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')o=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*o;
}
const int N=1e5+5;
int n,m,maxn,minn=1<<30,f[N],g[N],q[N];
struct node{int x,y;}a[N];
inline bool cmp(node x,node y){return x.x==y.x?x.y<y.y:x.x<y.x;}
inline bool check(int mid){
    int l=1,r=0;
    for(int i=1;i<=n;++i){
        while(l<=r&&a[i].y<=a[q[r]].y)--r;
        q[++r]=i;
        while(l<=r&&a[i].x-a[q[l]].x>mid)++l;
        f[i]=a[q[l]].y;
    }
    l=1,r=0;
    for(int i=1;i<=n;++i){
        while(l<=r&&a[i].y>=a[q[r]].y)--r;
        q[++r]=i;
        while(l<=r&&a[i].x-a[q[l]].x>mid)++l;
        g[i]=a[q[l]].y;
    }
    for(int i=1;i<=n;++i)if(g[i]-f[i]>=m)return 1;
    return 0;
}
int main(){
    n=read();m=read();
    for(int i=1;i<=n;++i){
        a[i].x=read(),a[i].y=read();
        minn=min(minn,a[i].y);maxn=max(maxn,a[i].y);
    }
    if(maxn-minn<m){puts("-1");return 0;}
    sort(a+1,a+n+1,cmp);
    int l=0,r=1000000,mid,ans;
    while(l<=r){
        mid=(l+r)>>1;
        if(check(mid))ans=mid,r=mid-1;
        else l=mid+1;
    }
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/PPXppx/p/11851813.html
Recommended