Codeforces Round #625 Div. 2 D E

D title: https://codeforces.com/contest/1321/problem/D

Meaning of the questions: Title to a directed graph, and then to a sequence, we have to walk along this sequence, process and asked to go to the current point in the shortest t reconstructs how many times the smallest maximum possible output

Analysis: The end is the same, we went to a location in accordance with the sequence of time, to the end there are several pieces of the same length shortest, thus there is also the maximum and minimum possible;

   We consider the shortest dis [] (each point to the end point of the distance) process simulation we go, the current point u, the next point v, obviously, when dis [u] +1! = Dis [v] when, It will certainly be reconstructed;

   When tantamount, do not add the least possible contribution, the maximum weight on the side of u there create another satisfying dis [u] + 1 == dis [k] (k! = V), if present, may be added to the maximum a contribution

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int M=2e5+6;
#define pb push_back
struct node{
    int v,cost;
    node(int vv=0,int cc=0):v(vv),cost(cc){}
    bool operator<(const node &b)const{
        return cost>b.cost;
    }
};
struct edge{
    int v,cost;
    edge(int vv=0,int cc=0):v(vv),cost(cc){}
};
vector<edge>g1[M],g2[M];
int vis[M],dis[M],a[M];
void dij(int n,int s){
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)
        dis[i]=inf;
    priority_queue<node>que;
    while(!que.empty())
        que.pop();
    dis[s]=0;
    que.push(node(s,0));
    while(!que.empty()){
        node now=que.top();
        que.pop();
        int u=now.v;
        if(vis[u])
            continue;
        vis[u]=1;
        for(int i=0;i<g2[u].size();i++){
            int v=g2[u][i].v;
            int cost=g2[u][i].cost;
            if(!vis[v]&&dis[v]>dis[u]+cost){
                dis[v]=dis[u]+cost;
                que.push(node(v,dis[v]));
            }
        }
    }
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    while(m--){
        int u,v;
        scanf("%d%d",&u,&v);
        g1[u].pb(edge(v,1));
        g2[v].pb(edge(u,1));
    }
 
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
        scanf("%d",&a[i]);
    dij(n,a[m]);
 
    int ans1=0,ans2=0;
    for(int i=2;i<=m;i++){
        int x=a[i-1],y=a[i];
        if(dis[x]!=dis[y]+1)
            ans1++,ans2++;
        else{
            int flag=0;
            for(int i=0;i<g1[x].size();i++){
                int v=g1[x][i].v;
                if(v!=y&&dis[x]==dis[v]+1){
                    flag=1;
                    break;
                }
            }
            ans2+=flag;
        }
    }
    printf("%d %d\n",ans1,ans2);
    return 0;
}
View Code

E questions:

The meaning of problems: Given n sword, m shield, each shield has both a sword and val properties and cost, p a monster, Vala each monster has three attributes (attributes corresponding to a sword), Valb (corresponding to the shield property), cost. Topics requirements must choose a sword shield, the answer will result in cost consumption; you can attribute strictly less than your chosen weapon to destroy the monster monster to get the cost added to the contribution required to output a maximum contribution;

Analysis: We consider enumerate every vala as a maximum, than vala little monster sure the candidate queue, and then select the shield consider what position to make the best answer;

   Because the maximum value of our vala enumeration, we must select the [valb + 1, max] of the shield, involving interval, interval maximum value is required, we can consider solved by segment tree, so we put every pieces move to the valb, the segment tree [valx + 1, max] coupled with its cost, means that we chose shield attributes [valb + 1, max], you can get his contribution to the cost;

   During enumeration, we vala certainly be put vala ascending process, put the line segment that has been treated trees was added, to take the maximum interval;

   We use the tree line to solve the shield and shield monsters handling of property, then the monster sword for sword and property, as long as we find the first location than the current vala large pos, and then in the [pos sword sequence in ascending order of attributes, n], to find the minimum cost, maybe by adding the most optimal solution is the current maximum vala;

   /// actual process separated two portions, a portion (sword / shield of monsters) and another portion (sword / shield of monster), any remaining maintain a data structure with a greedy solution directly;

using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll INF=1e18; 
const int M=1e6+6;
#define pb push_back
#define lson root<<1,l,midd
#define rson root<<1|1,midd+1,r
struct node{
    ll val,cost;
    bool operator<(const node &no)const{
        return val<no.val;
    }
}a[M+6],b[M+6];
struct Node{
    ll vala,valb,cost;
    bool operator<(const Node &No)const{
        return vala<No.vala;
    }
}c[M+6];
ll tr[(M<<2)+6],ly[(M<<2)+6];
ll all[M+6],tmp[M+6],suf[M+6];
void up(int root){
    tr[root]=max(tr[root<<1],tr[root<<1|1]);
}
void pushdown(int root,int l,int r){
    if(ly[root]){
        ll x=ly[root];
        tr[root<<1]+=x;
        ly[root<<1]+=x;
        tr[root<<1|1]+=x;
        ly[root<<1|1]+=x;
        ly[root]=0;
    }
}
void build(int root,int l,int r){
    if(l==r){
        tr[root]=-tmp[l];
        return ;
    }
    int midd=(l+r)>>1;
    build(lson);
    build(rson);
    up(root);
}
void update(int L,int R,ll c,int root,int l,int r){
    if(L<=l&&r<=R){
        tr[root]+=c;
        ly[root]+=c;
        return ;
    }
    pushdown(root,l,r);
    int midd=(l+r)>>1;
    if(L<=midd)
        update(L,R,c,lson);
    if(R>midd)
        update(L,R,c,rson);
    up(root); 
}
ll query(int L,int R,int root,int l,int r){
    if(L<=l&&r<=R){
        return tr[root];
    }
    if(ly[root])
        pushdown(root,l,r);
    int midd=(l+r)>>1;
    ll res=-INF;
    if(L<=midd)
        res=query(L,R,lson);
    if(R>midd)
        res=max(res,query(L,R,rson));
    up(root);
    return res;
}
int main(){
    int n,m,p;
    scanf("%d%d%d",&n,&m,&p);
    ll minn1=INF,minn2=INF;
    for(int i=1;i<=n;i++)
        scanf("%lld%lld" , & A [I] .val, & A [I] .cost), minn1 = min (minn1, A [I] .cost);
     for ( int I = . 1 ; I <= m; I ++ ) 
        Scanf ( " % LLD LLD% " , B & [I] .val, & B [I] .cost), minn2 = min (minn2, B [I] .cost); 
    LL ANS = -minn1-minn2; /// because topic that must be selected shield and sword, it is not considered destroyed monster directly subtracting the minimum; 
    Sort (a + . 1 , a + . 1 + n-); 
    Sort (B + . 1 , B + . 1 + m);
     for ( int I = . 1 ; I <= n-; I ++ ) 
        All [I] =A [I] .val;
 //     All [n +. 1] = INF; 
    /// seeking i ~ n of the minimum consumption sword 
    SUF [n + . 1 ] = INF;
     for ( int I = n; I> = . 1 ; i-- ) 
        SUF [i] = min (a [i] .cost, SUF [i + . 1 ]);
     /// initialization segment tree, and most certainly contribute to a number value of b i of the minimum cost the negative 
    for ( int I = 0 ; I <= m; I ++ ) 
        tmp [I] = INF;
     for ( int I = . 1 ; I <= m; I ++ ) 
        tmp [B [I] .val] =  min (tmp [b [i] .val], b [i] .cost);
    Build ( . 1 ,1,M-1);
    for(int i=1;i<=p;i++)
        scanf("%lld%lld%lld",&c[i].vala,&c[i].valb,&c[i].cost);
    sort(c+1,c+1+p);
    for(int i=1;i<=p;i++){
    //    cout<<ans<<endl;
        update(c[i].valb+1,M-1,c[i].cost,1,1,M-1);
        RES1 LL = Query (C [I] .valb +1, M- . 1 , . 1 , . 1 , M- . 1 ); /// shield and monsters contribution to answer 
    //     COUT RES1 << << endl; 
        int POS = upper_bound, (+ All . 1 , All + . 1 + n-, C [I ] .vala) - All; 
        LL RES2 = SUF [POS]; /// selected in the present case the optimum consumption sword 
        ANS = max (ANS, res1- RES2); 
    } 
    the printf ( " % LLD \ n- " , ANS);
     return  0 ; 
} 
Contest / 1321 / problem / E
View Code

 

Guess you like

Origin www.cnblogs.com/starve/p/12398306.html