제출 #99608

#제출 시각아이디문제언어결과실행 시간메모리
99608ae04071Palembang Bridges (APIO15_bridge)C++11
100 / 100
311 ms11580 KiB
#include <bits/stdc++.h>
#define fi first
#define se second
#define sz(x) ((int)(x).size())
using namespace std;
using lli = long long;
using pii = pair<int,int>;

int k,n;
vector<pii> arr;
lli ta[100001];

const int MAX=1<<18;
struct seg_tr{
    int cnt[MAX<<1];
    lli val[MAX<<1];
    
    void init() {for(int i=0;i<MAX+MAX;i++) val[i]=cnt[i]=0;}
    void upd(int cur,int s,int f,int idx,int v) {
        if(f<idx || s>idx) return;
        else if(s==f) {
            cnt[cur]++; val[cur]+=v;
        }
        else {
            int nx=cur<<1,md=(s+f)>>1;
            upd(nx,s,md,idx,v); upd(nx+1,md+1,f,idx,v);
            cnt[cur] = cnt[nx] + cnt[nx+1];
            val[cur] = val[nx] + val[nx+1];
        }
    }
    int kth(int cur,int s,int f,int k) {
        if(s==f) return s;
        else {
            int nx=cur<<1,md=(s+f)>>1;
            if(cnt[nx] >= k) return kth(nx,s,md,k);
            else return kth(nx+1,md+1,f,k-cnt[nx]);
        }
    }
    lli get(int cur,int s,int f,int idx,int v) {
        if(s==f) return 0;
        else {
            int nx=cur<<1,md=(s+f)>>1;
            if(idx<=md) return val[nx+1] - 1ll*cnt[nx+1]*v + get(nx,s,md,idx,v);
            else return 1ll*cnt[nx]*v - val[nx] + get(nx+1,md+1,f,idx,v);
        }
    }
}seg_tr;

lli solve() {
    vector<int> pa;
    n = sz(arr);
    if(!n) return 0;
    for(int i=0;i<n;i++) pa.push_back(arr[i].fi), pa.push_back(arr[i].se);

    sort(arr.begin(),arr.end(),[](const pii &a,const pii &b) {
        return a.fi+a.se < b.fi+b.se;
    });

    sort(pa.begin(),pa.end());
    pa.erase(unique(pa.begin(),pa.end()),pa.end());

    lli ret = 1000000000000000000ll;
    seg_tr.init();
    for(int i=0;i<n;i++) {
        int i1 = lower_bound(pa.begin(),pa.end(),arr[i].fi) - pa.begin(),
            i2 = lower_bound(pa.begin(),pa.end(),arr[i].se) - pa.begin();
        seg_tr.upd(1,0,MAX-1,i1,arr[i].fi);
        seg_tr.upd(1,0,MAX-1,i2,arr[i].se);
       
        int mi = seg_tr.kth(1,0,MAX-1,i+1);
        ta[i] = seg_tr.get(1,0,MAX-1,mi,pa[mi]);
    }
    if(k==1) return ta[n-1];
    seg_tr.init();
    for(int i=n-1;i>=0;i--) {
        int mi = seg_tr.kth(1,0,MAX-1,n-i-1);
        if(i==n-1) mi=0;
        ret = min(ret, ta[i] + seg_tr.get(1,0,MAX-1,mi,pa[mi]));

        int i1 = lower_bound(pa.begin(),pa.end(),arr[i].fi) - pa.begin(),
            i2 = lower_bound(pa.begin(),pa.end(),arr[i].se) - pa.begin();
        seg_tr.upd(1,0,MAX-1,i1,arr[i].fi);
        seg_tr.upd(1,0,MAX-1,i2,arr[i].se);
    }
    return ret;
}
int main() {
    lli ans=0;
    scanf("%d%d",&k,&n);
    for(int i=0;i<n;i++) {
        int a,b;
        char ca,cb;
        scanf(" %c %d %c %d",&ca,&a,&cb,&b);
        if(a>b) swap(a,b);
        if(ca==cb) ans += b-a;
        else arr.push_back(pii(a,b));
    }
    ans += solve();
    ans += n;
    printf("%lld\n",ans);
    return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

bridge.cpp: In function 'int main()':
bridge.cpp:89:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d%d",&k,&n);
     ~~~~~^~~~~~~~~~~~~~
bridge.cpp:93:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf(" %c %d %c %d",&ca,&a,&cb,&b);
         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...