NOI2019 elected to do

Construction ......

Here is a synchronous contestant, synchronous game play copper, the following content from the Internet, any similarity please understand ......

d1t1 route home

d1t1

Make complaints

The title of the first data range a little water, a little water followed by data, which leads to the question really became a sign problem.

The scene of a fairy: I find it difficult to see the \ (<100 \) points of the players.

However, I dish was dead, only took up the practice compiled false \ (90 \) ......

Algorithm 1

Set \ (f (i, j) \) represents the time \ (I \) to a point \ (J \) minimum required waiting time.
\ [f (q_x, y_x) = \ min \ {f (i, j) + F (p_x-i) \} (i \ le p_x) \] enumeration time for each time point enumeration state transition legitimate and recording status can be.

Complexity \ (O (nT) \) , where \ (T = \ max \ {Q_I \} \) . able to pass.

Algorithm 1 Code

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
inline int gi()
{
    char c=getchar(); int x=0;
    for(;c<'0'||c>'9';c=getchar());
    for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+c-'0';
    return x;
}
const int N=2e5+5;
int n,m,a,b,c,x[N],y[N],p[N],q[N],mxt;
int f[1005][100005];
bool vis[1005][100005];
inline int F(int x) {
    return a*x*x+b*x+c;
}
vector<int> v[N],avi[N];
int main()
{
    freopen("route.in","r",stdin);
    freopen("route.out","w",stdout);
    n=gi(),m=gi(),a=gi(),b=gi(),c=gi();
    for(int i=1;i<=m;++i)
    {
        x[i]=gi(),y[i]=gi(),p[i]=gi(),q[i]=gi(),mxt=max(mxt,q[i]);
        v[x[i]].push_back(i);
    }
    f[0][1]=0,avi[0].push_back(1);
    for(int t=0;t<=mxt;++t)
    {
        for(int it1=0;it1<avi[t].size();++it1)
        {
            int i=avi[t][it1];
            for(int it2=0;it2<v[i].size();++it2)
            {
                int j=v[i][it2];
                if(p[j]>=t)
                {
                    if(!vis[q[j]][y[j]])
                    {
                        vis[q[j]][y[j]]=true;
                        f[q[j]][y[j]]=f[t][i]+F(p[j]-t);
                        avi[q[j]].push_back(y[j]);
                    }
                    else f[q[j]][y[j]]=min(f[q[j]][y[j]],f[t][i]+F(p[j]-t));
                }
            }
        }
    }
    int ans=2147483647;
    for(int t=0;t<=mxt;++t) if(vis[t][n]) ans=min(ans,f[t][n]+t);
    printf("%d",ans);
}

Algorithm 2

The above approach is not out of question that people intent (the topic for explosion might intopen \ (T \ Le 10 ^ 3 \) )

Correct answer is optimized slope. Set \ (f (i) \) represented by the second \ (I \) minimum time to wait sides.
\ [F (i) = \
min \ {f (j) + A (p_i-q_j) ^ 2 + B (p_i-q_j) + C \} (q_j \ le p_i, y_j = x_i) \] Finally, the answer is \ (\ min \ {f ( i) + q_i \} (y_i = n) \)

Obviously the above formula is in the form of a slope optimized:
\ [F (I) = \ min \ {F (J) ^ 2 + Aq_j-Bq_j-2Bp_iq_j \} ^ 2 + Ap_i Bp_i + C + \]

\[ f(j)+Aq_j^2-Bq_j-2Bp_iq_j\le f(k)+Aq_k^2-Bq_k-2Bp_iq_k \]

\ [(F (j) + Aq_j ^ 2-Bq_j) - (f (k) ^ 2 + Aq_k-B) \ the 2Bp_i (q_j-q_k) \]

\[ \frac{g(j)-g(k)}{q_j-q_k}\le 2Bp_i \]

Therefore, we maintain a monotonic queue for each point, respectively \ (p_i, q_i \) ordered enumeration \ (P_i \) , the \ (q_j \ le p_i \) point was added to the transfer queue as described above.

Complexity \ (O (m \ log m) \) . This problem can be done to sort the linear range is small, but not necessary.

Algorithm 2 Code

#include<bits/stdc++.h>
using namespace std;
inline int gi()
{
    char c=getchar(); int x=0;
    for(;c<'0'||c>'9';c=getchar());
    for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+c-'0';
    return x;
}
typedef long long ll;
const int N=2e5+5,M=1e6+6;
int n,m;
ll f[N],g[N];
struct node {
    int u,v,s,e,id;
} a[N],b[N];
bool cmpe(node x, node y) {
    return x.e<y.e;
}
bool cmps(node x, node y) {
    return x.s<y.s;
}
vector<int> st[M];
int l[M],r[M],A,B,C;
void update(int x)
{
    int p=b[x].v,i=b[x].id;
    for(;l[p]<r[p]&&(g[st[p][r[p]]]-g[st[p][r[p]-1]])*(a[i].e-a[st[p][r[p]]].e)
        >=(g[i]-g[st[p][r[p]]])*(a[st[p][r[p]]].e-a[st[p][r[p]-1]].e);--r[p])
            st[p].pop_back();
    st[p].push_back(i); ++r[p];
}
int F(int x) { return A*x*x+B*x+C; }
void solve(int x)
{
    int p=a[x].u;
    for(;l[p]<r[p]&&(g[st[p][l[p]+1]]-g[st[p][l[p]]])
        <=2ll*A*a[x].s*(a[st[p][l[p]+1]].e-a[st[p][l[p]]].e);++l[p]);
    f[x]=f[st[p][l[p]]]+F(a[x].s-a[st[p][l[p]]].e);
    g[x]=f[x]+1ll*A*a[x].e*a[x].e-B*a[x].e;
}
int main()
{
    n=gi(),m=gi(),A=gi(),B=gi(),C=gi();
    for(int i=1;i<=m;++i) a[i].u=gi(),a[i].v=gi(),a[i].s=gi(),a[i].e=gi();
    sort(a+1,a+1+m,cmps);
    for(int i=1;i<=m;++i) b[i]=a[i],b[i].id=i,l[i]=0,r[i]=0;
    st[1].push_back(0);
    for(int i=2;i<=m;++i) st[i].push_back(m+1);
    f[m+1]=g[m+1]=1ll<<40;
    sort(b+1,b+1+m,cmpe);
    for(int i=1,j=1;i<=m;++i)
    {
        for(;j<=m&&b[j].e<=a[i].s;++j) update(j);
        solve(i);
    }
    ll ans=1ll<<60;
    for(int i=1;i<=m;++i) if(a[i].v==n) ans=min(ans,f[i]+a[i].e);
    printf("%lld",ans);
}

d1t3 sequence

d1t3

Solution

Let's consider two cases:

First, the current elected not common elements \ (<KL \) , then the optimal strategy in a certain sequence selected two largest;

If you do not currently share the elements \ (KL = \) , then we take the greatest in the following:

  1. \ (a_i + b_i \) in the largest;
  2. \ (a_i \) took \ (B_i \) did not get the \ (B_i \) maximum + \ (a_i \) maximum;
  3. \ (b_i \) took \ (a_i \) did not get in \ (a_i \) maximum + \ (b_i \) maximum.

The above selection method increases the \ (1 \ sim 2 \) a common pair.

We can use five heap may be maintained separately delete such information. Note to real-time statistics do not share the current number of elements.

Complexity \ (O (n \ log n ) \)

Code

#include<bits/stdc++.h>
using namespace std;
namespace io {
    const int SIZE=(1<<21)+1;
    char ibuf[SIZE],*iS,*iT,obuf[SIZE],*oS=obuf,*oT=oS+SIZE-1,c,qu[55]; int x;
    #define gc()(iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),(iS==iT?EOF:*iS++)):*iS++)
    inline int gi (){
        for(c=gc();c<'0'||c>'9';c=gc());
        for(x=0;c<='9'&&c>='0';c=gc()) x=(x<<1)+(x<<3)+(c&15); return x;
    }
}
using io::gi;
const int N=2e5+5;
struct node {
    int a,b,id;
} s[N];
bool cmpa(node x, node y) { return x.a>y.a; }
bool cmpb(node x, node y) { return x.b>y.b; }
bool cmpid(node x, node y) { return x.id<y.id; }
bool visa[N],visb[N];
typedef pair<int,int> pr;
struct heap
{
    priority_queue<pr> q;
    bool b[N];
    void push(int x, int y) { q.push(make_pair(x,y)); }
    void del(int x) { b[x]=true; }
    pr top()
    {
        while(!q.empty()&&b[q.top().second]) q.pop();
        if(q.empty()) return make_pair(-1e9,0);
        return q.top();
    }
    void pop()
    {
        while(!q.empty()&&b[q.top().second]) q.pop();
        q.pop();
    }
    void clear()
    {
        while(!q.empty()) q.pop();
        memset(b,false,sizeof(b));
    }
} q1,q2,q3,p1,p2;
int main()
{
    int T=gi();
    while(T--)
    {
        q1.clear(),q2.clear(),q3.clear(),p1.clear(),p2.clear();
        memset(visa,false,sizeof(visa));
        memset(visb,false,sizeof(visb));
        int n=gi(),k=gi(),l=gi(),cnt=0;
        for(int i=1;i<=n;++i) s[i].a=gi(),s[i].id=i;
        for(int i=1;i<=n;++i) s[i].b=gi();
        sort(s+1,s+1+n,cmpa);
        long long ans=0;
        for(int i=1;i<=k-l;++i) ans+=s[i].a,visa[s[i].id]=true;
        sort(s+1,s+1+n,cmpb);
        for(int i=1;i<=k-l;++i) ans+=s[i].b,visb[s[i].id]=true;
        sort(s+1,s+1+n,cmpid);
        for(int i=1;i<=n;++i)
        {
            if(!visa[i]&&!visb[i])
            {
                q1.push(s[i].a+s[i].b,i);
                p1.push(s[i].a,i),p2.push(s[i].b,i);
            }
            else if(!visa[i]) q2.push(s[i].a,i),p1.push(s[i].a,i);
            else if(!visb[i]) q3.push(s[i].b,i),p2.push(s[i].b,i);
            else ++cnt;
        }
        while(l--)
        {
            pr a1=q1.top(),b1;
            pr a2=q2.top(),b2=p2.top();
            pr a3=q3.top(),b3=p1.top();
            if(cnt)
            {
                a1=p1.top(),b1=p2.top();
                if(a1.first+b1.first>a2.first+b2.first&&a1.first+b1.first>a3.first+b3.first)
                {
                    --cnt,p1.pop(),p2.pop(); ans+=a1.first+b1.first;
                    if(!visa[a1.second]&&!visb[a1.second])
                    {
                        q1.del(a1.second);
                        q3.push(s[a1.second].b,a1.second);
                    }
                    else q2.del(a1.second),++cnt;
                    visa[a1.second]=true;
                    if(!visa[b1.second]&&!visb[b1.second])
                    {
                        q1.del(b1.second);
                        q2.push(s[b1.second].a,b1.second);
                    }
                    else q3.del(b1.second),++cnt;
                    visb[b1.second]=true;
                    continue;
                }
            }
            if(a1.first>a2.first+b2.first&&a1.first>a3.first+b3.first)
            {
                q1.pop(); ans+=a1.first;
                visa[a1.second]=visb[a1.second]=true;
                p1.del(a1.second),p2.del(a1.second);
            }
            else if(a2.first+b2.first>a3.first+b3.first)
            {
                q2.pop(),p2.pop(); ans+=a2.first+b2.first;
                visa[a2.second]=true;
                p1.del(a2.second);
                if(!visa[b2.second]&&!visb[b2.second])
                {
                    q1.del(b2.second);
                    q2.push(s[b2.second].a,b2.second);
                }
                else q3.del(b2.second),++cnt;
                visb[b2.second]=true;
            }
            else
            {
                q3.pop(),p1.pop(); ans+=a3.first+b3.first;
                visa[a3.second]=true;
                p2.del(a3.second);
                if(!visa[b3.second]&&!visb[b3.second])
                {
                    q1.del(b3.second);
                    q3.push(s[b3.second].b,b3.second);
                }
                else q2.del(b3.second),++cnt;
                visa[b3.second]=true;               
            }
        }
        printf("%lld\n",ans);
    }
}

d2t1 bounce

d2t1

Solution

Dijkstra's algorithm execution considered: selecting a shortest each minimum point, by which it is attached to the slack point. Generally, we use the shortest stack to maintain the current minimum point.

Since the present point in question is connected to each point of a rectangle, while the right side is equal to all the connection points, so we need to take a rectangular support \ (\ min \) , the minimum overall query.

We can use the KD-Tree to maintain, the complexity of the \ (O (n-(\} + n-sqrt {\ log n-)) \) .

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=3e5+5,inf=1<<30;
inline void chmin(int& x, int y) { x=(x<y?x:y); }
inline void chmax(int& x, int y) { x=(x>y?x:y); }
inline int gi()
{
    char c=getchar(); int x=0;
    for(;c<'0'||c>'9';c=getchar());
    for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+c-'0';
    return x;
}
bool vis[N];
struct node
{
    int d[2],mx[2],mn[2],l,r;
    int w,tg,id,mnw,mnid;
    bool del,alldone;
    void up(node x)
    {
        chmin(mn[0],x.mn[0]);
        chmax(mx[0],x.mx[0]);
        chmin(mn[1],x.mn[1]);
        chmax(mx[1],x.mx[1]);
    }
} st[N];
int now,dis[N],tot,n,m,w,h,rt,nw,x[N],y[N];
int p[N],t[N],l[N],r[N],d[N],U[N];
bool cmp(node x, node y) {
    return x.d[now]<y.d[now];
}
void pushup(node& x)
{
    if(st[x.l].alldone&&st[x.r].alldone&&x.del)
    {
        x.alldone=true;
        return ;
    }
    if(x.del) x.w=x.mnw=x.mnid=inf+1;
    else x.mnw=min(x.w,x.tg),x.mnid=x.id;
    if(!st[x.l].alldone&&st[x.l].mnw<x.mnw) x.mnw=st[x.l].mnw,x.mnid=st[x.l].mnid;
    if(!st[x.r].alldone&&st[x.r].mnw<x.mnw) x.mnw=st[x.r].mnw,x.mnid=st[x.r].mnid;
    x.mnw=min(x.mnw,x.tg);
}
void pushdown(node x)
{   chmin(st[x.l].tg,x.tg);
    chmin(st[x.r].tg,x.tg);
}
int build(int l, int r, bool d)
{
    int mid=l+r>>1; now=d;
    nth_element(st+l+1,st+mid+1,st+r+1,cmp);
    st[mid].mx[0]=st[mid].mn[0]=st[mid].d[0];
    st[mid].mx[1]=st[mid].mn[1]=st[mid].d[1];
    st[mid].w=st[mid].mnw=st[mid].tg=inf;
    if(l!=mid) st[mid].l=build(l,mid-1,d^1),st[mid].up(st[st[mid].l]);
    if(r!=mid) st[mid].r=build(mid+1,r,d^1),st[mid].up(st[st[mid].r]);
    pushup(st[mid]);
    return mid;
}
void del(int u, int x, int y)
{
    if(st[u].alldone||x<st[u].mn[0]||x>st[u].mx[0]||y<st[u].mn[1]||y>st[u].mx[1]) return ;
    pushdown(st[u]);
    if(st[u].d[0]==x&&st[u].d[1]==y)
    {
        st[u].del=true;
        pushup(st[u]);
        return ; 
    }
    if(!st[st[u].l].alldone) del(st[u].l,x,y);
    if(!st[st[u].r].alldone) del(st[u].r,x,y);
    pushup(st[u]);
}
void cover(int u, int xl, int xr, int yl, int yr, int w)
{
    if(st[u].alldone||xr<st[u].mn[0]||xl>st[u].mx[0]||yr<st[u].mn[1]||yl>st[u].mx[1]) return ;
    if(st[u].tg<=w) return ;
    if(xl<=st[u].mn[0]&&st[u].mx[0]<=xr&&yl<=st[u].mn[1]&&st[u].mx[1]<=yr)
    {
        chmin(st[u].tg,w);
        pushup(st[u]);
        return ;
    } 
    pushdown(st[u]);
    if(xl<=st[u].d[0]&&st[u].d[0]<=xr&&yl<=st[u].d[1]&&st[u].d[1]<=yr) chmin(st[u].w,w);
    if(!st[st[u].l].alldone) cover(st[u].l,xl,xr,yl,yr,w);
    if(!st[st[u].r].alldone) cover(st[u].r,xl,xr,yl,yr,w);
    pushup(st[u]);
}
vector<int> v[N];
int main()
{
    n=gi(),m=gi(),w=gi(),h=gi();
    for(int i=1;i<=n;++i) x[i]=st[i].d[0]=gi(),y[i]=st[i].d[1]=gi(),st[i].id=i;
    st[0].alldone=true;
    rt=build(1,n,0);
    for(int i=1;i<=m;++i)
    {
        p[i]=gi(),t[i]=gi(),l[i]=gi(),r[i]=gi(),d[i]=gi(),U[i]=gi();
        v[p[i]].push_back(i);
    }
    dis[1]=0,cover(rt,x[1],x[1],y[1],y[1],0);
    while(!st[rt].alldone)
    {
        int u=st[rt].mnid;
        if(vis[u]) continue;
        vis[u]=true;
        dis[u]=st[rt].mnw;
        del(rt,x[u],y[u]);
        for(int i=0;i<v[u].size();++i)
            cover(rt,l[v[u][i]],r[v[u][i]],d[v[u][i]],U[v[u][i]],dis[u]+t[v[u][i]]);
    }
    for(int i=2;i<=n;++i) printf("%d\n",dis[i]);
}

d2t3 I king of adventure

d2t1

Solution

According to a theory of the official solution to a problem, every time we randomizing a permutation \ (the p-\) , find attached before each point in the array of points, if the number of attached points is odd then at least you can find a way.

Conclusion The official solution to a problem, at least \ (N / 3 \) point is connected to the front edges of the odd.

You can use whole-half points for each find even point in front of. Specifically, change all point to the left and to the right point in the original color of the left has changed into the left point, the rest of the points put right.

The complexity of the solution to a problem of Official Analytical, since the variation amount of the operation and the like on both sides, we need to take three equal division points each partition.

Attention to detail to achieve, save the information inquiry, to ensure that no unnecessary inquiry conducted operations.

(Forget the official explanations or directly see it)

Code

#include "explore.h"
#include <bits/stdc++.h>
using namespace std;
const int N=3e5+5;
int n,m,now,p[N];
vector<int> v;
bool tmp[N],del[N];
bool mp[N],l[N];
int head[N],nxt[N<<1],to[N<<1],tot;
namespace task1
{
void solve()
{
    for(int i=0;i<n-1;++i)
    {
        if(check(i)) continue;
        modify(i);
        l[i]^=1;
        for(int j=i+1;j<n;++j)
        {
            int x=query(j);
            if(l[j]!=x) l[j]=x,report(i,j);
        }
    }
}
}
void addedge(int u, int v) {
    nxt[++tot]=head[u], head[u]=tot, to[tot]=v;
}
void solve(int l, int r, vector<int> v, bool d)
{
    if(l==r)
    {
        for(int i=0;i<v.size();++i)
            if(p[v[i]]!=p[l])
            {
                ++now;
                report(p[v[i]],p[l]);
                addedge(p[v[i]],p[l]),addedge(p[l],p[v[i]]);
            }
        if(!d) modify(p[l]);
        return ;
    }
//  int mid=l+r>>1;
    int mid=l+(r-l+1)/3;
    for(int i=l;i<=mid;++i) mp[p[i]]=true;
    if(d) for(int i=l;i<=mid;++i) modify(p[i]);
    else for(int i=mid+1;i<=r;++i) modify(p[i]);
    vector<int> v1,v2;
    for(int i=0;i<v.size();++i)
    {
        int x=query(p[v[i]]);
        for(int e=head[p[v[i]]];e;e=nxt[e]) x^=mp[to[e]];
        if(v[i]<=mid||x) v1.push_back(v[i]);
        else v2.push_back(v[i]);
    }
    for(int i=l;i<=mid;++i) mp[p[i]]=false;
    solve(l,mid,v1,0),solve(mid+1,r,v2,1);
}
void explore(int N, int M)
{
    n=N,m=M;
    if(n<=500)
    {
        task1::solve();
        return ;
    }
    for(int i=0;i<n;++i) p[i]=i;
    while(true)
    {
        int nm=n; n=0;
        for(int i=0;i<nm;++i) if(!del[p[i]]) p[n++]=p[i];
        if(N%10!=7) random_shuffle(p,p+n);
        v.clear();
        for(int i=0;i<n;++i) v.push_back(i);
        solve(0,n-1,v,1);
        if(now==m) break;
        for(int i=0;i<n;++i) if(check(p[i])) del[p[i]]=true;
    }
}

Guess you like

Origin www.cnblogs.com/farway17/p/11259020.html