QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#40862 | #3998. The Profiteer | XZTsmallmax67 | TL | 3ms | 7968kb | C++ | 3.2kb | 2022-07-27 08:59:41 | 2022-07-27 08:59:42 |
Judging History
answer
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+1e3,inf=1e18;
int n,K,E;
int a[N],b[N],v[N];
struct BAG
{
stack<vector<int> >stk;
void Prepare(){vector<int>vt;vt.resize(K+1);vt[0]=0;stk.push(vt);}
void add(int w,int v)
{
vector<int>dp;dp=stk.top();
for(int i=K;i>=w;i--)dp[i]=max(dp[i],dp[i-w]+v);
stk.push(dp);
}
int get(vector<int>dp)
{
int res=0;
for(int i=1;i<=K;i++)res+=dp[i];
return res;
}
int get(){return get(stk.top());}
void revoke(int cur)
{
while(stk.size()>cur)stk.pop();
}
}F;
int ans[N];
int check(){return F.get()<=E;}
int pd(int l,int r,int L,int R)
{
int cur1=F.stk.size();
for(int i=l;i<=r;i++)F.add(b[i],v[i]);
for(int i=L;i<=R;i++)F.add(a[i],v[i]);
// cout<<F.get()<<endl;
int pd=check();F.revoke(cur1);
return pd;
}
int work(int l,int r)
{
int ans=0;
while(l<r)
{
int mid=l+r>>1;
// cout<<l<<' '<<mid<<" "<<r<<endl;
if(pd(l,mid,mid+1,r))//mid 可行
{
int rr=r;r=mid;
for(int i=rr;i>r;i--){F.add(a[i],v[i]);}
}
else
{
int ll=l;l=mid+1;
for(int i=ll;i<l;i++){F.add(b[i],v[i]);}
}
}
return l;
}
void solve(int l,int r,int L,int R)
//询问区间为 l ~ r,值域在 L ~ R (合法的最左边的右端点)
//显然有决策单调性
{
if(l>r||L>R)return;
if(L==R){for(int i=l;i<=r;i++)ans[i]=L;return;}
int mid=l+r>>1,cur1=F.stk.size();
for(int i=mid;i<min(r+1,L);i++)F.add(b[i],v[i]);
int cur2=F.stk.size();
for(int i=l;i<mid;i++)F.add(a[i],v[i]);
ans[mid]=work(max(mid,L),R);
F.revoke(cur2);
// for(int i=max(mid,L);i<=R;i++)
// {
// F.add(b[i],v[i]);
// int cur3=F.stk.size();
// for(int j=i+1;j<=R;j++)F.add(a[j],v[j]);
// if(check()){ans[mid]=i;break;}
// F.revoke(cur3);
// }
// F.revoke(cur2);
// if(!ans[mid])ans[mid]=n+1;
for(int i=ans[mid]+1;i<=R;i++)F.add(a[i],v[i]);
solve(l,mid-1,L,ans[mid]);
F.revoke(cur1);
for(int i=max(r+1,L);i<ans[mid];i++)F.add(b[i],v[i]);
for(int i=l;i<=mid;i++)F.add(a[i],v[i]);
solve(mid+1,r,ans[mid],R);
F.revoke(cur1);
}
signed main()
{
scanf("%lld%lld%lld",&n,&K,&E);E*=K;
F.Prepare();
for(int i=1;i<=n;i++)scanf("%lld%lld%lld",&v[i],&a[i],&b[i]);
solve(1,n,1,n+1);
// for(int i=1;i<=n;i++)printf("%lld ",ans[i]);
// puts("");
// for(int i=1;i<=n;i++)F.add(b[i],v[i]);
// for(int i=1;i<=n;i++)
// {
// F.revoke(1);
// for(int j=1;j<i;j++)F.add(a[j],v[j]);
// int cur=F.stk.size();
// for(int j=i;j<=n+1;j++)
// {
// ans[i]=j;
// F.revoke(cur);
// for(int k=i;k<=j;k++)F.add(b[k],v[k]);
// for(int k=j+1;k<=n;k++)F.add(a[k],v[k]);
// if(check())break;
// }
// printf("%lld ",ans[i]);
// }
int res=0;
for(int i=1;i<=n;i++)res+=n-ans[i]+1;
printf("%lld\n",res);
return 0;
}
/*
4 5 3
3 2 4
1 2 3
2 1 2
3 1 3
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 3ms
memory: 7968kb
input:
4 5 3 3 2 4 1 2 3 2 1 2 3 1 3
output:
1
result:
ok single line: '1'
Test #2:
score: 0
Accepted
time: 1ms
memory: 7860kb
input:
4 5 4 3 2 4 1 2 3 2 1 2 3 1 3
output:
3
result:
ok single line: '3'
Test #3:
score: 0
Accepted
time: 1ms
memory: 7964kb
input:
4 5 5 3 2 4 1 2 3 2 1 2 3 1 3
output:
7
result:
ok single line: '7'
Test #4:
score: -100
Time Limit Exceeded
input:
200000 50 23333 2620 5 21 8192 17 34 6713 38 46 6687 13 42 390 9 13 4192 7 37 7898 17 21 1471 16 45 3579 22 40 9628 8 23 7164 28 45 3669 14 31 5549 29 35 4670 30 39 5811 15 20 4162 18 29 7590 29 41 7786 23 35 383 9 40 5576 39 46 5586 4 9 1110 14 33 8568 4 6 8548 39 42 9133 10 42 6679 22 39 8353 33 3...