布谷。
欢迎大家来不耻下问。
这里是正解不会,暴力写跪,乱搞鸡肋的某虻 。
好想放假啊!!!!
话说猫厂现在产量低迷……
ZJ一下:
T1,三维偏序,只码了$Theta(N^2)$暴力
T2,暴力愉快。
T3,输〇片分。
简单TJ:
T1
因为这个题的要求比较特殊,求解的答案可以和一个输入的顺序一起维护。
首先通过排序将$A$数组的偏序限制解决
然后用树状数组暴干$B$数组的大小,将位置插入树状数组比较维护。
最后的答案直接查即可。
#include <algorithm> #include <iostream> #include <cstring> #include <climits> #include <vector> #include <cstdio> #define N 555555 #define LL long long using namespace std; const int lim=500000; LL pn; struct PRE{ LL id,pa,pb; }ps[N]; vector<LL>vls; LL pre[N]; LL ans=0; inline LL fvind(LL a){ return lower_bound(vls.begin(),vls.end(),a)-vls.begin()+1; } inline LL lowbit(int x){ return x&(-x); } void add(LL pos,LL val){ while(pos<=lim){ pre[pos]=min(pre[pos],val); pos+=lowbit(pos); } } LL query(LL pos){ LL res=LLONG_MAX; while(pos){ res=min(res,pre[pos]); pos-=lowbit(pos); } return res; } int main(){ LL a; ios_base::sync_with_stdio(false); cin>>pn; for(int i=1;i<=pn;i++)ps[i].id=i; for(int i=1;i<=pn;i++){ cin>>a; ps[i].pa=ps[i-1].pa+a; } vls.push_back(0); for(int i=1;i<=pn;i++){ cin>>a; ps[i].pb=ps[i-1].pb+a; vls.push_back(ps[i].pb); } // for(auto i:vls){ cout<<i<<" "; }cout<<endl; sort(vls.begin(),vls.end()); vls.erase(unique(vls.begin(),vls.end()),vls.end()); // for(auto i:vls){ cout<<i<<" "; }cout<<endl; for(int i=0;i<=pn;i++){ ps[i].pb=fvind(ps[i].pb); } sort(ps,ps+pn+1,[](const PRE &a,const PRE &b) {return a.pa==b.pa?a.id<b.id:a.pa<b.pa;}); // for(int i=1;i<=pn;i++){ cout<<ps[i].pa<<" "<<ps[i].pb<<" "<<ps[i].id<<endl; } memset(pre,0x7f,sizeof pre); // add(ps[0].pb,0); for(int i=0;i<=pn;i++){ LL vl=query(ps[i].pb);//cout<<ps[i].id<<"val:"<<vl<<endl; add(ps[i].pb,ps[i].id); ans=max(ans,ps[i].id-vl); } cout<<ans<<endl; }
T2
证明先咕下。
利用决策单调性,将$Theta(N^3)$优化成$Theta(N^2)$
#include <iostream> #include <climits> #include <cstring> #include <cstdio> #define N 5555 #define LL long long using namespace std; int pn; LL arr[N],pre[N], dp[N][N], ap[N][N]; int main(){ cin.sync_with_stdio(false); cin>>pn; for(int i=1;i<=pn;i++){ cin>>arr[i]; pre[i]=pre[i-1]+arr[i]; } for(int i=1;i<=pn;i++){ for(int j=1;j<=pn;j++){ if(i<=j)dp[i][j]=LLONG_MAX/3; else dp[i][j]=0; } } for(int i=1;i<=pn;i++){ dp[i][i]=arr[i]; ap[i][i]=i; } for(int i=1;i<pn;i++){ for(int j=1;j+i<=pn;j++){ int l=j,r=j+i; // cout<<l<<" "<<r<<endl; // cout<<ap[l][r-1]<<"~"<<ap[l+1][r]<<endl; for(int k=ap[l][r-1];k<=ap[l+1][r];k++){ // cout<<dp[l][r]<<" <<<< "<<dp[l][k-1]<<"+"<<dp[k+1][r]<<endl; if(dp[l][r]>dp[l][k-1]+dp[k+1][r]){ dp[l][r]=dp[l][k-1]+dp[k+1][r]; ap[l][r]=k; } } dp[l][r]+=pre[r]-pre[l-1]; } } cout<<dp[1][pn]<<endl; }
T3
大神题,好像和一些神奇的高斯消元有关。