5月集训Day2考试

第三题%SWH大神

目录

      • Divisors
      • Market
      • Dash Speed

Divisors

5月集训Day2考试_第1张图片
暴力拆因数+数组离散化
要不是不知道一个数最多有几个因数就A了,怕开不下。。。

#include 
#include 
using namespace std;

const int MAXM=205,MAXN=600005;
int a[MAXM],brk[MAXN],ans[MAXM];

inline int read();

inline void div(const int &now){
    for(int i=1;i*i<=a[now];++i){
        if(a[now]%i==0){
            brk[++brk[0]]=i;
            if(i*i!=a[now])
                brk[++brk[0]]=a[now]/i;
        }
    }
}

int main(){
    freopen("div.in","r",stdin);
    freopen("div.out","w",stdout);
    int n=read(),m=read();
    for(int i=1;i<=m;++i){
        a[i]=read();
        div(i);
    }
    brk[++brk[0]]=~0U>>1;
    sort(brk+1,brk+brk[0]+1);
    int tot=0;
    for(int i=1,cnt=1;i0] && brk[i]<=n;++i){
        if(brk[i]==brk[i+1]) ++cnt;
        else{
            ++ans[cnt];
            ++tot;
            cnt=1;
        }
    }
    ans[0]=n-tot;
    for(int i=0;i<=m;++i)
        printf("%d\n",ans[i]);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

inline int read(){
    char c; int x;
    while(c=getchar(),c<'0' || '9''0';
    while(c=getchar(),'0'<=c && c<='9')
        x=x*10+c-'0';
    return x;
}

Market

5月集训Day2考试_第2张图片
5月集训Day2考试_第3张图片
dp,dp,啊。。。先离线处理一下时间顺序就A了。。。

#include 
#include 
using namespace std;
#define min(a,b) (a
#define max(a,b) (a>b ? a:b)

const int MAXN=305,MAXM=100005;
const long long INF=~0ULL>>2;
long long dp[MAXM];
int n,m,lim,ans[MAXN];

struct shop{
    int c,v,t;
}d[MAXN];
bool cmp1(const shop &a,const shop &b){
    if(a.t!=b.t) return a.tif(a.c!=b.c) return a.creturn a.v>b.v;
}

struct plan{
    int no,t,m,pos;
}q[MAXM];
bool cmp2(const plan &a,const plan &b){
    if(a.pos!=b.pos) return a.pospos;
    if(a.m!=b.m) return a.m>b.m;
    if(a.t!=b.t) return a.treturn a.nono;
}

inline int read();

inline int find(const int &i){
    int l=1,r=n,mid,rt=0;
    while(r>=l){
        mid=(l+r)>>1;
        if(d[mid].t>q[i].t)
            r=mid-1;
        else{
            rt=max(rt,mid);
            l=mid+1;
        }
    }
    return rt;
}

int main(){
    freopen("market.in","r",stdin);
    freopen("market.out","w",stdout);
    n=read(),m=read();
    for(int i=1;i<=n;++i){
        d[i].c=read();
        d[i].v=read();
        d[i].t=read();
        lim+=d[i].v;
    }
    sort(d+1,d+n+1,cmp1);
    for(int i=1;i<=m;++i){
        q[i].t=read();
        q[i].m=read();
        q[i].no=i;
        q[i].pos=find(i);
    }
    sort(q+1,q+m+1,cmp2);
    for(int i=1;i<=lim;++i)
        dp[i]=INF;
    int k=1;
    while(!q[k].pos && k<=m) ++k;
    for(int i=1;i<=n;++i){
        for(int j=lim;j>=d[i].v;--j)
            dp[j]=min(dp[j],dp[j-d[i].v]+d[i].c);
        for(int j=lim;q[k].pos==i && k<=m;++k){
            for(;j>=1;--j){
                if(dp[j]<=q[k].m){
                    ans[q[k].no]=j;
                    break;
                }
            }
        }
    }
    for(int i=1;i<=m;++i)
        printf("%d\n",ans[i]);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

inline int read(){
    char c; int x;
    while(c=getchar(),c<'0' || '9'x=c-'0';
    while(c=getchar(),'0'<=c && c<='9')
        x=x*10+c-'0';
    return x;
}

Dash Speed

%%%SWH大神,生成树+按秩合并+线段树上的CDQ分治

#include 
#include 
#include 
using namespace std;
#define min(a,b) ((a)^(((a)^(b))&(-((a)>(b)))))
#define max(a,b) ((a)^(((a)^(b))&(-((a)<(b)))))

inline int read();
inline void swap(int &a,int &b);

const int MAXN=70005,MAXM=140005;
int n,m;
int he[MAXN],de[MAXN],ans[MAXN];
int rank[MAXN],fa[MAXN]; //union-find set
int st[MAXN][20]; //with dfn[],pos[], used for RMQ_LCA
int dfn[MAXM]; //the inorder list
int pos[MAXN]; //node NO.u's first pos in dfn
int cnt;

stack<int> s;

struct line{
    int u,v,nex;
}ed[MAXM];

struct node{
    int ls,rs,lp,rp;
};

struct chain{
    int u,v; //lp,rp
}ln[MAXM];
//ln[i]: the longest chain the line NO.i in

struct change{
    int pre_u,pre_v,u,v,sz;
}opt[MAXM];

int find(const int &x){
    return fa[x] ? x:find(fa[x]);
}

inline void add(int he[],line ed[],int &cnt,const int &u,const int &v){
    ed[++cnt].nex=he[u];
    he[u]=cnt;
    ed[cnt].u=u;
    ed[cnt].v=v;
}

struct segT{
    int cnt,he[MAXM],tot;
    node d[MAXM];
    line ed[MAXM];
    segT(){cnt=1;}
    void build(const int &u,int l,int r){
        d[u].lp=l,d[u].rp=r;
        if(l==r) return;
        int mid=(l+r)>>1;
        d[u].ls=++cnt;
        build(d[u].ls,l,mid);
        d[u].rs=++cnt;
        build(d[u].rs,mid+1,r);
    }
    void ist(const int &u,const int &l,const int &r){
        if(l<=d[u].lp && d[u].rp<=r){
            add(he,ed,tot,l,r);
            return;
        }
        int mid=(d[u].lp+d[u].rp)>>1;
        if(r<=mid) ist(d[u].ls,l,r);
        if(l>mid) ist(d[u].rs,l,r);
    }
}T;

void dfs(const int &u,const int &fa){
    dfn[++dfn[0]]=u;
    de[u]=de[fa]+1;
    for(int i=he[u],v;i;i=ed[i].nex){
        v=ed[i].v;
        if(v!=fa){
            dfs(v,u);
            dfn[++dfn[0]]=u;
        }
    }
}

inline void st_load(){
    for(int i=1;i<=dfn[0];++i)
        st[i][0]=i;
    for(int i=1;i<20;++i){
        for(int j=1;j+(1<1<=cnt;++j){
            if(de[dfn[st[j][i-1]]]1<<(i-1))][i-1]]])
                st[j][i]=st[j][i-1];
            else st[j][i]=st[j+(1<<(i-1))][i-1];
        }
    }
}

inline int get_len(const int &u,const int &v){
    int posu=pos[u],posv=pos[v];
    if(posu>posv) swap(posu,posv);
    int k=log(posv-posu+1)/log(2);
    return de[u]+de[v]-(min(de[dfn[st[posu][k]]],de[dfn[st[posv-(1<1][k]]]<<1));
}

int max_len(const int &now){
    int fu=find(T.ed[now].u),fv=find(T.ed[now].v);
    chain tmp;
    int lenu=get_len(ln[fu].u,ln[fv].v);
    int lenv=get_len(ln[fv].u,ln[fv].v);
    int len;
    if(lenu>lenv){
        len=lenu;
        tmp=ln[fu];
    }
    else{
        len=lenv;
        tmp=ln[fv];
    }
    //circumstances in which the two chain get together
    int len_uv;
    len_uv=get_len(ln[fu].u,ln[fv].u);
    if(len_uv>len){
        len=len_uv;
        tmp.u=ln[fu].u;
        tmp.v=ln[fv].u;
    }
    len_uv=get_len(ln[fu].u,ln[fv].v);
    if(len_uv>len){
        len=len_uv;
        tmp.u=ln[fu].u;
        tmp.v=ln[fv].v;
    }
    len_uv=get_len(ln[fu].v,ln[fv].u);
    if(len_uv>len){
        len=len_uv;
        tmp.u=ln[fu].v;
        tmp.v=ln[fv].u;
    }
    len_uv=get_len(ln[fu].v,ln[fv].v);
    if(len_uv>len){
        len=len_uv;
        tmp.u=ln[fu].v;
        tmp.v=ln[fv].v;
    }
    if(rank[fu]>rank[fv]){
        opt[now].u=fv;
        opt[now].v=fu;
        opt[now].pre_u=ln[fu].u;
        opt[now].pre_v=ln[fu].v;
        fa[fv]=fu;
    }
    else{
        opt[now].u=fu;
        opt[now].v=fv;
        opt[now].pre_u=ln[fv].u;
        opt[now].pre_v=ln[fv].v;
        fa[fu]=fv;
        if(rank[fu]==rank[fv]){
            ++rank[fv];
            opt[now].sz=1;
        }
    }
    return len;
}

//reset the option
inline void reset(const int &now){
    for(int i=T.he[now];i;i=T.ed[i].nex)
        s.push(i);
    while(s.size()){
        ln[opt[s.top()].v].u=opt[s.top()].pre_u;
        ln[opt[s.top()].u].v=opt[s.top()].pre_v;
        fa[opt[s.top()].v]=0;
        rank[opt[s.top()].v]-=opt[s.top()].sz;
        s.pop();
    }
}

//divid and conquer
void solve(const int &u,int s){
    for(int i=T.he[u];i;i=T.ed[i].nex)
        s=max(s,max_len(i));
    if(T.d[u].lp==T.d[u].rp){
        ans[T.d[u].lp]=s;
        reset(u);
        return;
    }
    solve(T.d[u].ls,s);
    solve(T.d[u].rs,s);
    reset(u);
}

int main(){
    freopen("speed.in","r",stdin);
    freopen("speed.out","W",stdout);
    n=read(),m=read();
    T.build(1,1,n);
    for(int i=1,u,v,l,r;i1,l,r);
    }
    dfs(1,0);
    st_load();
    for(int i=1;i<=n;++i)
        ln[i].u=ln[i].v=i; //what?
    solve(1,0);
    for(int i=1,q;i<=m;++i){
        q=read();
        printf("%d\n",ans[q]);
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

inline int read(){
    char c; int x;
    while(c=getchar(),c<'0' || '9''0';
    while(c=getchar(),'0'<=c && c<='9')
        x=x*10+c-'0';
    return x;
}

inline void swap(int &a,int &b){
    a^=b,b^=a,a^=b;
}

你可能感兴趣的:(题解)