[luogu 1108 & 2687] [USACO4.3] Buy Low, Buy Lower

Title:

I am a hyperlink

Explanation:

It's just water. Most people should be able to do it. Suddenly, I want to challenge nlogn's approach, and then...
b[i] denotes the number of schemes ending in I
The first question in dichotomy is how to count the number of projects.
Every number stored in G is replaced by a number larger than ta, that is to say, if all g values are recorded, it will increase monotonously, so that every time G is updated, the number of schemes is the sum of the number of previous digital schemes larger than his.
But soon the blogger found this idea extremely difficult to achieve: you can't deal with the number of solutions with the same number, you can neither ignore it [add it up, it's not repeated before], nor replace it completely [empty the previous one, although the last one is the best, but the previous one that ends with other numbers is also gone], in a word, make an ans statistics brief. No way to play.
What about www? The blogger sees a way to put n++ and the last a in a very small number, so that all the solutions can be summed up.
woc is so scientific. Why didn't I think of it?
This question needs more precision than the one you are familiar with. There are four bloggers in it.

Code:

#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
struct hh{int tim,z;};
vector<hh>nxt[5005];
int n,i,a[5005],g[5005],ans,ll[5005];
struct bignum{int l,a[500];void cl(){memset(a,0,sizeof(a));l=0;}}b[5005];
void gjj(bignum &a,bignum b)
{
    a.l+=b.l;int x=0;
    for (int i=1;i<=a.l;i++)
    {
        a.a[i]=a.a[i]+b.a[i]+x;
        x=a.a[i]/10000;
        a.a[i]%=10000;
    }
    while (!a.a[a.l]) a.l--;
}
int main()
{
    scanf("%d",&n);
    for (i=1;i<=n;i++) scanf("%d",&a[i]);
    int tot=0,maxx=0;
    a[++n]=-1e9;
    for (i=1;i<=n;i++)
    {
        int l=1,r=tot;
        while (l<=r)
        {
            int mid=(l+r)>>1;
            if (g[mid]<=a[i]) r=mid-1;
            else l=mid+1;
        }
        int now=i;
        if (!nxt[r+1].size() || a[i]!=a[nxt[r+1][nxt[r+1].size()-1].tim])//Avoid adding duplicate numbers 
          nxt[r+1].push_back((hh){i,a[i]});
        else now=nxt[r+1][nxt[r+1].size()-1].tim;
        b[now].cl();//Set the previous zero, because as the end, the number behind must be better than the previous one. 

        if (r)
        for (int j=ll[r];j<nxt[r].size();j++)
        {
            if (nxt[r][j].z<=a[i]) ll[r]++;
            else gjj(b[now],b[nxt[r][j].tim]);
        }
        g[r+1]=a[i];
        tot=max(tot,r+1);
        if (b[now].l==0) b[now].l=1,b[now].a[1]=1; 
        //The way to deal with it is to overlay the previous one as it has been repeated before, because at last a minimum is added manually, and all the previous schemes are grouped together. 
    }
    printf("%d ",tot-1);
    //High Precision Pressure 4 Bits
    printf("%d",b[n].a[b[n].l]);
    for (i=b[n].l-1;i>=1;i--)
    {
        printf("%d",b[n].a[i]/1000);
        printf("%d",b[n].a[i]/100%10);
        printf("%d",b[n].a[i]/10%10);
        printf("%d",b[n].a[i]%10);
    }
}

Posted by rajb on Wed, 13 Feb 2019 09:06:19 -0800