cf 1257 E. The Contest (good title) (LIS / thinking)

Meaning of the questions:

There are three sequences, a, b, c, each operation can be a mobile number in a sequence to another sequence,

Q, the minimum operation several times, it may cause less than all the number of all the numbers b in the inside of a sequence, b which is smaller than the inside c.

Digital is not repeated, the amount of data a total of 2e5.

 

Ideas:

A practice: (LIS)

This approach is in line to see, really quite clever, using this method, even at a later sequence of 100, need not be afraid.

Respectively abc sorted and then merged,

Seeking maximum rise subsequence, then the rise in the number sequence does not move, move only in the non-sequential, the answer is n - len, len maximum, the answer is a minimum.

Seeking LIS time, with Fenwick tree optimize it, so is the complexity to O (log the n-* the n-  ).

 

Practice two fucks :()

This is blind himself to think out of the complexity of O (n), but applies only to three sequences.

Three in the sequence, referred to as the color of the three colors seen c1, c2, c3, and then mixed with sorting,

Then each time a left fixing point L, indicates to the last 1 ~ l in a sequence number, a lookup operation can be minimized right point r, represents the last l + 1 ~ r in the number of sequence b, then the remaining r + 1 ~ n is a number in the sequence c.

How to find the right point of the minimum operating it r, l assume does not exist, that is, we now only the sequence is divided into two sections,

When the right end point i, obviously, the number of operands is 1 ~ c3, i + 1 to i plus the number of n, c2, (this is the required number of operation sequences bc) (number of times of operation of a well seeking, is not the number of 1 ~ l c1 Lane)

Why can not assume the presence of l, l because when moving, if a swallow c3, then, the R & lt l + 1 ~ n operands each time point is all minus one, so the position of the minimum change, but a minus value only.

Only two points, we can easily find the minimum value r in j ~ n when, from the updated this would look like a forward.

 

So, in short, is a position where the minimum of the pre-j ~ n r in, then enumeration L, update answers.

(Every time I thought the question put all thoughts of a mess ...)

 

Code:

A practice: (LIS)

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <functional>
using namespace std;
const int maxn = 2e5 + 10;
const int inf = 0x3f3f3f3f;
int dp[maxn],mx[maxn];
int lowbit(int i){
    return i & (-i);
}
void insert(int i,int x,int n){
    while(i <= n){
        mx[i] = max(mx[i],x);
        i += lowbit(i);
    }
}
int _find(int i){
    int res = 0;
    while(i > 0){
        res = max(mx[i],res);
        i -= lowbit(i);
    }
    return res;
}

int LIS(int a[],int n){
    int res = 0;
    memset(mx,0,sizeof(mx));
    memset(dp,0,sizeof(dp));
    for(int i = 1;i <= n;i++){
        dp[a[i]] = _find(a[i]) + 1;
        res = max(res,dp[a[i]]);
        insert(a[i],dp[a[i]],n);
    }
    return res;
}
int a[maxn],b[maxn];
int main(){
    int _n[3],n;
    while(scanf("%d%d%d",&_n[0],&_n[1],&_n[2]) != EOF){
        n = 0;
        int cnt = 0;
        for(int k = 0;k < 3;k++){
            for(int i = 1;i <= _n[k];i++)
                scanf("%d",&b[i]);
            sort(b + 1,b + _n[k] + 1);
            for(int i = 1;i <= _n[k];i++)
                a[++cnt] = b[i];
            n += _n[k];
        }
        
        int ans = LIS(a,n);
        printf("%d\n",n - ans);
    }
    return 0;
}
View Code

 

Practice two fucks :()

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 10;
int sum2[maxn],sum3[maxn],mi_p[maxn],mi[maxn];
int vis[maxn];
int main(){
    int n1,n2,n3,x,n;
    while(scanf("%d%d%d",&n1,&n2,&n3) != EOF){
        memset(vis,0,sizeof(vis));
        n = n1 + n2 + n3;
        for(int i = 1;i <= n1;i++){
            scanf("%d",&x);
            vis[x] = 1;
        }
        for(int i = 1;i <= n2;i++){
            scanf("%d",&x);
            vis[x] = 2;
        }
        for(int i = 1;i <= n3;i++){
            scanf("%d",&x);
            vis[x] = 3;
        }

        sum3[0] = 0;
        for(int i = 1;i <= n;i++){
            sum3[i] = sum3[i - 1];
            if(vis[i] == 3)
                sum3[i]++;
        }
        sum2[n + 1] = 0;
        for(int i = n;i >= 1;i--){
            sum2[i] = sum2[i + 1];
            if(vis[i] == 2)
                sum2[i]++;
        }

        int mival = sum3[n],ans = 1e9;
        mi[n] = sum3[n];
        for(int i = n - 1;i >= 1;i--){
            mi[i] = mi[i + 1];
            if(mival > sum3[i] + sum2[i + 1]){
                mival = sum3[i] + sum2[i + 1];
                mi[i] = mival;
            }
        }
        mi[0] = min(sum2[1],mi[1]);
        
        int one = 0,sub = 0,res;
        ans = n2 + n3;
        for(int i = 0;i < n;i++){
            if(vis[i] == 1)
                one++;
            if(vis[i] == 3)
                sub++;
            res = (i - one) + mi[i] - sub + (n1 - one);
            if(res < ans)
                ans = res;
        }
        printf("%d\n",ans);
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/InitRain/p/12543640.html