이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#pragma once
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#define ll long long
const int N=1e6+200;
int MN=3003;
int seg_cnt[N];
long long seg_sum[N];
void Update(int i,ll val=-1,int v=1,int s=0,int e=MN)
{
if(i<s or e<i)
return;
if(s==e)
{
seg_cnt[v]++;
if(val==-1)
seg_sum[v]+=i;
else
{
seg_sum[v]+=val;
}
return;
}
int mid=(s+e)/2;
Update(i,val,2*v,s,mid);
Update(i,val,2*v+1,1+mid,e);
seg_cnt[v]=seg_cnt[2*v]+seg_cnt[2*v+1];
seg_sum[v]=seg_sum[2*v]+seg_sum[2*v+1];
}
void Update1(int i,ll val=-1,int v=1,int s=0,int e=MN)
{
if(i<s or e<i)
return;
if(s==e)
{
seg_cnt[v]--;
if(val==-1)
seg_sum[v]-=i;
else
seg_sum[v]-=val;
return;
}
int mid=(s+e)/2;
Update1(i,val,2*v,s,mid);
Update1(i,val,2*v+1,1+mid,e);
seg_cnt[v]=seg_cnt[2*v]+seg_cnt[2*v+1];
seg_sum[v]=seg_sum[2*v]+seg_sum[2*v+1];
}
int get_cnt(int l,int r,int v=1,int s=0,int e=MN)
{
if(r<s or e<l)
return 0;
if(l<=s and e<=r)
return seg_cnt[v];
int mid=(s+e)/2;
return get_cnt(l,r,2*v,s,mid)+get_cnt(l,r,2*v+1,mid+1,e);
}
long long get_sum(int l,int r,int v=1,int s=0,int e=MN)
{
if(r<s or e<l)
return 0;
if(l<=s and e<=r)
return seg_sum[v];
int mid=(s+e)/2;
return get_sum(l,r,2*v,s,mid)+get_sum(l,r,2*v+1,mid+1,e);
}
long long findMaxAttraction(int n, int cc, int d, int a[])
{
vector<int> op,dp;
for(int i=0;i<n;i++)
op.push_back(a[i]);
sort(begin(op),end(op));
op.resize(unique(begin(op),end(op))-begin(op));
for(int i=0;i<n;i++)
dp.push_back(lower_bound(begin(op),end(op),a[i])-begin(op));
long long ans=0;
for(int left=cc;left>=0;left--)
{
Update(dp[left],a[left]);
{
int right=cc;
ll tmie=min(right-cc,cc-left)+right-left;
if(tmie<=d)
{
int s=-1;
int e=MN+1;
while(s+1<e)
{
int mid=(s+e)/2;
if((get_cnt(mid,MN)+tmie)>d)
{
s=mid;
}
else
{
e=mid;
}
}
long long cur=get_sum(s+1,MN);
if(s!=-1)
{
cur+=(op[s]*(d-tmie-get_cnt(s+1,MN)));
}
ans=max(ans,cur);
}
}
for(int right=cc+1;right<n;right++)
{
Update(dp[right],a[right]);
ll tmie=min(right-cc,cc-left)+right-left;
if(tmie>d)
continue;
int s=-1;
int e=MN+1;
while(s+1<e)
{
int mid=(s+e)/2;
if((get_cnt(mid,MN)+tmie)>d)
{
s=mid;
}
else
{
e=mid;
}
}
long long cur=get_sum(s+1,MN);
if(s!=-1)
{
cur+=(op[s]*(d-tmie-get_cnt(s+1,MN)));
}
ans=max(ans,cur);
}
for(int right=cc+1;right<n;right++)
Update1(dp[right],a[right]);
}
return ans;
}
컴파일 시 표준 에러 (stderr) 메시지
holiday.cpp:1:9: warning: #pragma once in main file
1 | #pragma once
| ^~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |