A. Frais d'impression (réflexion + bissection + suffixe minimum / arbre de segment st / ligne)

Idée: trouvez d'abord un prix récent inférieur ou égal au prix actuel du papier, puis trouvez un moyen de compter rapidement la valeur minimale des prix suivants.

J'ai l'impression que cette question cf a été publiée.

Pour trouver l'emplacement, en raison de la monotonie, deux points peuvent être utilisés. Faites attention à la position où les deux points ne peuvent pas être trouvés.

Plus la constante recommandée est petite est le suffixe d'entretien minimum de l'esprit.

Contribuez à mon pool de code: maintenez la requête de suffixe minimum O (1) et comparez.

 


Parlez d'autres méthodes, maintenez la valeur minimale d'une séquence et d'une requête, vous pouvez st table ou arbre de segment de ligne, essayez st table. Mais la dichotomie a coincé la frontière. (Changeons l'article bipartite)

Il s'avère que la raison pour laquelle wa a été envoyé 8: quand il n'a pas été trouvé, l = n + 1; bien que la limite ait été prise, l--, mais la limite st pos = l + 1 que j'ai prise était toujours 0; résultant en wa. Effectivement, la façon de penser est moins sujette aux erreurs

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+1000;
typedef long long LL;
inline LL read()
{
	LL x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
LL n,m;
LL a[maxn],s[maxn],q[maxn];
LL f[maxn][40];
int main(void)
{
  	LL n,m;n=read();m=read();
  	///for(LL i=0;i<=n+10;i++) s[i]=1e18;
	for(int i=1;i<=n;i++) {
        s[i]=read();
        q[i]=read();
        a[i]=s[i]*q[i];
	}
	LL t=log(n)/log(2)+1;
	for(int i=1;i<=n;i++) f[i][0]=a[i];
	for(int j=1;j<t;j++)
		for(int i=1;i<=n-(1<<j)+1;i++)
			f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    while(m--){
        LL x;x=read();
        if(n==1){
            printf("%lld\n",x*q[1]);
            continue;
        }
       /// LL l=lower_bound(s+1,s+1+n,x)-s;
        LL l=upper_bound(s+1,s+1+n,x)-s-1;
        LL res=x*q[l];
        if(l==0) res=1e18;
        LL pos=l+1;
        if(pos<=n){
            LL k=log(n-pos+1)/log(2);
            LL ans2=min(f[pos][k],f[n-(1<<k)+1][k]);
            printf("%lld\n",min(ans2,res));
        }
		else printf("%lld\n",res);
    ///    debug(ans2);
    ///    debug(res);
       /// LL ans2=q[l]*x;
       /// debug(ans1);debug(ans2);

    }
return 0;
}

 

Je suppose que tu aimes

Origine blog.csdn.net/zstuyyyyccccbbbb/article/details/112912464
conseillé
Classement