hdu - 6406 Taotao Picks Apples(離線+離散+技巧)

題目鏈接:Taotao Picks Apples

題目大意:有n個數,m個操作,每個操作x,q,將x位的數字改爲q,輸出改完數後數組的遞增序列有多長(只能從第一個數開始找,並且必須依次找更大的數)。

思路:我是用離線的方法,先記錄x位置之前的有多少個數,然後再求x之後有多少個數,然後輸出就行了,之前的好算,之後的不是太好算。
之後的算法:
先用離散這n個數和更改的數,並且將最大的數離散爲最小的數,按照求最長嚴格遞增序列的長度來計算,但是要改一下,用lower_bound查找位置的時候,將這個位置之後的數都捨棄(就是這一點沒有想到,結果當時沒有AC,絕望)。

代碼:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=1e6+9;
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
typedef long long ll;

int a[maxn];
int b[maxn];
int c[maxn*2];
int d[maxn];
int vis[maxn];
struct node
{
    int x,y,h,sum;
} f[maxn];
vector<int>q[maxn];

int main()
{
    int t;
    int n,m;
    scanf("%d",&t);
    while(t--)
    {
        mem(vis,0);
        mem(a,0);
        mem(b,0);
        mem(c,0);
        mem(d,0);
        scanf("%d%d",&n,&m);
        int k=0;
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            c[k++]=a[i];
            q[i].clear();
        }
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d",&f[i].x,&f[i].y);
            f[i].h=f[i].sum=0;
            c[k++]=f[i].y;
            q[f[i].x].push_back(i);
            vis[f[i].x]=1;
        }
        sort(c,c+k);
        k=unique(c,c+k)-c;
        int sum=0;
        int h=0;
        for(int i=0; i<=n; i++)
        {
            if(a[i]>h)
            {
                h=a[i];
                sum++;
            }
            if(vis[i+1])
            {
                for(int j=0; j<q[i+1].size(); j++)
                {
                    f[q[i+1][j]].sum=sum;
                    f[q[i+1][j]].h=h;
                    if(f[q[i+1][j]].y>h)
                    {
                        f[q[i+1][j]].sum++;
                        f[q[i+1][j]].h=f[q[i+1][j]].y;
                    }
                }
            }
        }
        for(int i=1; i<=n; i++)
            b[n-i+1]=k-(lower_bound(c,c+k,a[i])-c);
        int p=0;
        for(int i=1; i<=n+1; i++)
        {
            if(vis[n-i+1])
            {
                for(int j=0; j<q[n-i+1].size(); j++)
                {
                    int p1=lower_bound(c,c+k,f[q[n-i+1][j]].h)-c;
                    int ff=lower_bound(d,d+p,k-p1)-d;
                    f[q[n-i+1][j]].sum+=ff;
                }
            }
            if(i==n+1) break;
            int p1=lower_bound(d,d+p,b[i])-d;
            d[p1]=b[i];
            p=p1+1;
        }
        for(int i=1; i<=m; i++)
            printf("%d\n",f[i].sum);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章