"Explanations" "CF853B" Jury Meeting

table of Contents

topic

Portal

Thinking

Very clever differential prefix and good questions.

After the end of the title plate, I see there are many ways to handle this problem, but the overall feel and relatively subtle difference prefix.

First, we can enter each person able to \ (0 \) dots stay the maximum time interval \ ([tl, tr] \ ) , and everyone \ ([tl, tr] \ ) intersected, get \ ([ll, rr] \ ) means that only in this interval everyone can come together.

Obviously, if the \ (rr-ll-1 < k \) directly puts("-1")to.

Then how to do? Assuming that everyone from time to gather \ (i \) began to \ (i + k + 1 \ ) or longer, then we can guarantee that their work is often at least \ (k \) , then we need to find is that all al ([1, i] \) \ period to \ (0 \) a minimum cost and \ ([i + k + 1 , n] \) minimum cost and the return period.

In both cases is the same, we discuss only one, wish to discuss access to \ (0 \) situations.

For one, we assume that he \ (i \) time to reach \ (0 \) cheapest price \ (m_i \) , then all of his travel \ (0 \) flight in chronological order from small to large order.

Provisions: \ (t_i \) represents \ (i \) flights departure time, \ (C_i \) for its cost, \ (m_i \) for the people in \ (i \) arrival time \ (0 \) the minimum cost.

Now we analyze his first flight hall and second flights, due to the \ (t \) we have sequential ordering, and now discuss \ (c \) the size of the relationship:

  1. \ (c_1 \ Le c_2 \) , then the first person to sit next flight is certainly the cheapest, but we can \ (m_i \) to modify the array, that is, \ (\ forall m_i, t_1 \ le i <t_3, = c_1 m_i \) , attention, here \ (i <t_3 \) instead of \ (t_2 \) (think about it, why)?;
  2. \ (c_1> c_2 \) , we found that at the moment, in time \ (i \) between the interval \ ([t_1, t_2) \ ) when, certainly can only take the first trip flight, but if \ (i \ ge t_2 \) , we take the second best flights doubt that when (t_1 \ le i <t_2 \ ) \ time, ) \ (m_i = c_1 \ , if \ (i \ le t_2 \) when, \ (m_i c_2 = \) ;

Our analysis will be extended to the entire system which:

In this enumeration are \ (I \) flights, the reservation \ (1,2, \ ldots i- 1 \) minimum cost of flights \ (\ min \) .

  • If \ (C_i <\ min \) , then we update \ (\ min \) , and washed with \ (C_i \) a \ (m_i, i \ in [ t_i, t_ {i + 1}) \) total update;
  • If \ (C_i \ GE \ min \) , then we retain the \ (\ min \) , and washed with \ (\ min \) a \ (m_i, i \ in [ t_i, t_ {i + 1}] \) total update ;

As from \ (0 \) to return hope all of you to analyze, because there are some code \ (+ 1 \) if no analysis is difficult to make sense of.

After analysis, we found that this operation is very much like interval assignment , then here there are many data structures and ideas worthy of our use:

  • Segment tree
  • Fenwick tree
  • Differential prefix and

Differential prefix and personal recommendation, because the former two modifications, are asked \ (\ mathcal O (\ log N) \) , the latter modifying \ (\ mathcal O (. 1) \) , asks \ (\ mathcal O (\ log N) \) , and based on our analysis seems to modify the operation is very complicated, and asks the operator only used when computing the final answer.

So we are for everyone, you can open a \ (ansl [i] [t ] \) indicates that the person \ (i \) in \ (t \) time to \ (0 \) , and then open a \ (ansr [ i] [t] \) indicates that this person again \ (T \) time leaving \ (0 \) . But people have \ (10 ^ 5 \) a time scale there \ (10 ^ 6 \) months, certainly not when opening a two-dimensional, but because people are independent, there is no impact, we consider all of the common a \ (ansl \) and a \ (ansr \) array.

Specific details, see code.

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<utility>
using namespace std;

#define rep(i,__l,__r) for(signed i=__l,i##_end_=__r;i<=i##_end_;++i)
#define fep(i,__l,__r) for(signed i=__l,i##_end_=__r;i>=i##_end_;--i)
#define writc(a,b) fwrit(a),putchar(b)
#define mp(a,b) make_pair(a,b)
#define ft first
#define sd second
#define LL long long
#define ull unsigned long long
#define uint unsigned int
#define pii pair< int,int >
#define Endl putchar('\n')
#define CODEFAIL puts("-1"),exit(0)
// #define FILEOI
// #define int long long
// #define int unsigned

#ifdef FILEOI
# define MAXBUFFERSIZE 500000
    inline char fgetc(){
        static char buf[MAXBUFFERSIZE+5],*p1=buf,*p2=buf;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXBUFFERSIZE,stdin),p1==p2)?EOF:*p1++;
    }
# undef MAXBUFFERSIZE
# define cg (c=fgetc())
#else
# define cg (c=getchar())
#endif
template<class T>inline void qread(T& x){
    char c;bool f=0;
    while(cg<'0'||'9'<c)f|=(c=='-');
    for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    if(f)x=-x;
}
inline int qread(){
    int x=0;char c;bool f=0;
    while(cg<'0'||'9'<c)f|=(c=='-');
    for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    return f?-x:x;
}
// template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}
inline int gcd(const int a,const int b){return b?gcd(b,a%b):a;}
inline void getInv(int inv[],const int lim,const int MOD){
    inv[0]=inv[1]=1;for(int i=2;i<=lim;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
}
template<class T>void fwrit(const T x){
    if(x<0)return (void)(putchar('-'),fwrit(-x));
    if(x>9)fwrit(x/10);
    putchar(x%10^48);
}
inline LL mulMod(const LL a,const LL b,const LL mod){//long long multiplie_mod
    return ((a*b-(LL)((long double)a/mod*b+1e-8)*mod)%mod+mod)%mod;
}

const int MAXN=1e5;
const int MAXM=1e5;
const int MAXK=1e6;
const int INF=(1<<30)-1;

int n,m,k,ll,rr;
vector< pii >a[MAXN+5],b[MAXN+5];
//a[i] : 第 i 个点到 0 点的时间, 花费
//b[i] : 0 点到 i 点的时间, 花费

inline void input(){
    n=qread(),m=qread(),k=qread();
    for(int i=1,d,f,t,c;i<=m;++i){//照常规输入即可
        d=qread(),f=qread(),t=qread(),c=qread();
        if(f==0)b[t].push_back(mp(d,c));
        else a[f].push_back(mp(d,c));
    }
}

inline void init(){
    ll=-1,rr=INF;
    int tl,tr;
    rep(i,1,n){
        sort(a[i].begin(),a[i].end());
        sort(b[i].begin(),b[i].end());
        tl=INF,tr=-1;
        if(!a[i].empty())tl=a[i].begin()->first;
        if(!b[i].empty())tr=b[i].back().first;
        if(tl==INF || tr==-1)CODEFAIL;//如果连来的机票或者回去的机票的没有, 直接 gg
        ll=Max(ll,tl),rr=Min(rr,tr);//取交集
        // printf("i == %d, tl == %d, tr == %d\n",i,tl,tr);
    }
    // printf("ll == %d, rr == %d\n",ll,rr);
    if(ll==-1 || rr==INF || rr-ll-1<k)CODEFAIL;//如果缺机票或者全部人最大的交集都不够 k 天也 gg 了
}

LL ansl[MAXK+5],ansr[MAXK+5],res=(1ll<<60)-1;
inline void solve(){
    for(int i=1,now,cost;i<=n;++i){
        now=1,cost=INF;//初始化
        // puts("For into ansl");
        for(int t=0,siz=a[i].size(),tmp;t<siz;++t){
            // printf("When i == %d, now == %d, cost == %d\n",i,now,cost);
            tmp=a[i][t].first;
            ansl[tmp]-=cost;
            ansl[now]+=cost;
            //差分前缀和的基本操作
            //注意:此处有别于下面, 原因在于这里是处理前往 0 点而非离开 0 点
            now=tmp,cost=Min(cost,a[i][t].second);
            // printf("After i == %d, now == %d, cost == %d\n",i,now,cost);
        }
        ansl[MAXK+1]-=cost;
        ansl[now]+=cost;
        now=MAXK,cost=INF;//倒着处理
        for(int t=b[i].size()-1,tmp;t>=0;--t){
            tmp=b[i][t].first;
            ansr[now+1]-=cost,ansr[tmp+1]+=cost;
            now=tmp,cost=Min(cost,b[i][t].second);
        }
        ansr[1]+=cost,ansr[now+1]-=cost;
        // printf("After i == %d, the two arr:\n",i);
        // rep(t,1,20)writc(ansl[t],' ');Endl;
        // rep(t,1,20)writc(ansr[t],' ');Endl;
    }
    rep(i,1,MAXK)ansl[i]+=ansl[i-1],ansr[i]+=ansr[i-1];//差分前缀和数组的最后一步
    // rep(i,1,20)writc(ansl[i],' ');
    // Endl;
    // rep(i,1,20)writc(ansr[i],' ');
    // Endl;
    for(int i=ll;i+k+1<=rr;++i)res=Min(res,ansl[i]+ansr[i+k+1]);
    writc(res,'\n');
}

signed main(){
#ifdef FILEOI
    freopen("file.in","r",stdin);
    freopen("file.out","w",stdout);
#endif
    input();
    init();
    solve();
    return 0;
}

Seems a bit greedy?

Guess you like

Origin www.cnblogs.com/Arextre/p/12291465.html
Recommended