无聊开始水题
退役已久假期无聊水了水题。
正解是前后缀单队背包n^2预处理mq询问,
用消失之物+单队水过了,n^2log预处理,o(q)询问;(毕竟和原题挺像的,第一个想到的就是这个)
#include<bits/stdc++.h> #define F(i,a,b) for(int i=a;i<=b;++i) #define LL long long #define pf(a) printf("%d ",a) #define phn puts("") using namespace std; int read(); /* 扫左走右,扫右走左。seg+单队背包 从0编号,询问编号加1*/ int n; const int N =1110; int a[N],b[N],c[N]; int ans[N][N],f[N],g[2][N],que[N],hd,tl; void cal(int &p,int i){ p=!p; for(int j=0;j<a[i];++j){ hd=1;que[tl=1]=j;g[p][j]=g[!p][j]; for(int k=j+a[i];k<=1000;k+=a[i]){ g[p][k]=max(g[!p][que[hd]]+(k-que[hd])/a[i]*b[i],g[!p][k]); while(hd<=tl&&que[hd]+c[i]*a[i]<k+a[i])++hd; while(hd<=tl&&g[!p][que[tl]]+(k-que[tl])/a[i]*b[i]<g[!p][k])--tl; que[++tl]=k; } } } void dp(int l,int r){ if(l==r){memcpy(ans[l],f,sizeof(f));return;} int z=l+r>>1; int sto[N]={0}; //memset sto memcpy(sto,f,sizeof(f)); //memset(g[1],0,sizeof(g[1])); int p=0; memcpy(g[0],f,sizeof(f)); F(i,z+1,r)cal(p,i); memcpy(f,g[p],sizeof(f)); dp(l,z); p=0; memcpy(g[0],sto,sizeof(sto)); F(i,l,z)cal(p,i); memcpy(f,g[p],sizeof(f)); dp(z+1,r); memcpy(f,sto,sizeof(f)); } int main(){ n=read(); F(i,1,n)a[i]=read(),b[i]=read(),c[i]=read(); dp(1,n); int m=read(); while(m--){ int id=read()+1,ee=read(); printf("%d\n",ans[id][ee]); } } int read(){ int s=0,f=0;char ch=getchar(); while(!isdigit(ch))f=ch=='-',ch=getchar(); while(isdigit(ch))s=s*10+(ch^48),ch=getchar(); return f?-s:s; } /* 5 2 3 4 1 2 1 4 1 2 2 1 1 3 2 3 5 1 10 2 7 3 4 4 8 0 5 */
ps:传统艺能:踩skyh博客
Informatik verbindet dich und mich.
信息将你我连结。