QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#44585 | #4585. Greedy Knapsack | eyiigjkn | ML | 3ms | 22100kb | C++14 | 2.9kb | 2022-08-19 14:10:05 | 2022-08-19 14:10:07 |
Judging History
answer
# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
constexpr int N=4000010;
constexpr double alp=0.2;
int w[100010],v[100010],stk[N],lc[N],rc[N],used[N],tot=0,cnt=0;
ll sz[N],len[N],val[N],addmk[N];
bool flag[N];
int newnode(ll s=0,ll l=0,ll v=0)
{
int cur=(stk[0]?stk[stk[0]--]:++tot);cnt++;
addmk[cur]=lc[cur]=rc[cur]=used[cur]=0;
sz[cur]=s;len[cur]=l;val[cur]=v;
return cur;
}
int copy(int rt)
{
int cur=(stk[0]?stk[stk[0]--]:++tot);cnt++;
tie(lc[cur],rc[cur],sz[cur],len[cur],val[cur],addmk[cur])=make_tuple(lc[rt],rc[rt],sz[rt],len[rt],val[rt],addmk[rt]);
used[cur]=1;
if(lc[cur]) used[lc[cur]]++;
if(rc[cur]) used[rc[cur]]++;
return cur;
}
void pushup(int rt)
{
if(!lc[rt]) return;
sz[rt]=sz[lc[rt]]+sz[rc[rt]];
len[rt]=len[lc[rt]]+len[rc[rt]];
val[rt]=max(val[lc[rt]],val[rc[rt]]);
}
void del(int rt)
{
if(!rt) return;
stk[++stk[0]]=rt;cnt--;
if(lc[rt] && !(--used[lc[rt]])) del(lc[rt]);
if(rc[rt] && !(--used[rc[rt]])) del(rc[rt]);
}
void update(int rt,ll x)
{
val[rt]+=x;addmk[rt]+=x;
}
void pushdown(int rt)
{
if(addmk[rt])
{
if(lc[rt])
{
int t=lc[rt];
update(lc[rt]=copy(t),addmk[rt]);
if(t && !(--used[t])) del(t);
}
if(rc[rt])
{
int t=rc[rt];
update(rc[rt]=copy(t),addmk[rt]);
if(t && !(--used[t])) del(t);
}
addmk[rt]=0;
}
}
int join(int x,int y)
{
int rt=newnode();
lc[rt]=x;rc[rt]=y;
used[x]++;used[y]++;
pushup(rt);
return rt;
}
int merge(int x,int y)
{
if(!x || !y) return x+y;
pushdown(x);pushdown(y);
if(min(sz[x],sz[y])>=alp*(sz[x]+sz[y])) return join(x,y);
if(sz[x]>=sz[y])
if(sz[lc[x]]>=alp*(sz[x]+sz[y])) return merge(lc[x],merge(rc[x],y));
else return pushdown(rc[x]),merge(merge(lc[x],lc[rc[x]]),merge(rc[rc[x]],y));
else
if(sz[rc[y]]>=alp*(sz[x]+sz[y])) return merge(merge(x,lc[y]),rc[y]);
else return pushdown(lc[y]),merge(merge(x,lc[lc[y]]),merge(rc[lc[y]],rc[y]));
}
void split(int rt,ll k,int &x,int &y)
{
if(!rt) return x=y=0,void();
if(sz[rt]==1)
if(!k) return x=0,y=rt,void();
else if(k==len[rt]) return x=rt,y=0,void();
else return x=newnode(1,k,val[rt]),y=newnode(1,len[rt]-k,val[rt]),void();
pushdown(rt);
if(k<=len[lc[rt]]) split(lc[rt],k,x,y),y=merge(y,rc[rt]);
else split(rc[rt],k-len[lc[rt]],x,y),x=merge(lc[rt],x);
}
void dfs(int rt)
{
if(!rt || flag[rt]) return;
flag[rt]=1;
dfs(lc[rt]);dfs(rc[rt]);
}
int main()
{
int n,rt;
ll m;
cin>>n>>m;
for(int i=1;i<=n;i++) scanf("%d",&w[i]);
for(int i=1;i<=n;i++) scanf("%d",&v[i]);
rt=newnode(1,m+1,0);
for(int i=n;i;i--)
{
int a,b,c,d;
split(rt,w[i],a,b);
split(rt,m-w[i]+1,c,d);
if(c) update(c,v[i]);
del(rt);del(b);del(d);
rt=merge(a,c);
if(!used[a]) del(a);
if(!used[c]) del(c);
if(cnt+1000>N)
{
cnt=stk[0]=0;dfs(rt);
for(int i=1;i<=tot;i++)
if(flag[i]) flag[i]=0,cnt++;
else stk[++stk[0]]=i;
}
}
cout<<val[rt]<<endl;
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 20056kb
input:
5 10 10 1 2 3 4 1 1 1 1 1
output:
3
result:
ok single line: '3'
Test #2:
score: 0
Accepted
time: 2ms
memory: 20128kb
input:
5 10000000000 10 1 2 3 4 30 2 15 7 11
output:
65
result:
ok single line: '65'
Test #3:
score: 0
Accepted
time: 3ms
memory: 20056kb
input:
5 20 4 9 5 1 3 203 175 131 218 304
output:
900
result:
ok single line: '900'
Test #4:
score: 0
Accepted
time: 2ms
memory: 22100kb
input:
1 1 1 1
output:
1
result:
ok single line: '1'
Test #5:
score: -100
Memory Limit Exceeded
input:
100000 200000 100000 99998 99996 99994 99992 99990 99988 99986 99984 99982 99980 99978 99976 99974 99972 99970 99968 99966 99964 99962 99960 99958 99956 99954 99952 99950 99948 99946 99944 99942 99940 99938 99936 99934 99932 99930 99928 99926 99924 99922 99920 99918 99916 99914 99912 99910 99908 999...