SDOI2016 Round 1解题报告

SDOI知识点大复习 马上就要考一轮了,也该复习一下模板了,把以前的题整理一下,再做一些经典题吧。 阅读详情

Day1
T1
题目大意:
已知n,m,k,求∑n−1i=0∑m−1j=0max((i xor j)−k,0)

题解:
可以按照数位dp的思想来做,每次考虑在当前这个数的二进制位和n,m这两个二进制位的大小,以及与k的大小,从状态f[i][j][k][l]转移到后继状态,复杂度是O(log(n)∗2∗2∗2∗3)。
但是数位dp毕竟难写难调,我们可以继续考虑,有一棵log(n)层的满二叉Trie,那它的每个叶子节点都可以对应一个0~n−1的数。那我们就可以根据这个想法一部分一部分的来考虑他们对答案的贡献了(左子树−>右子树),比较好写。
Ps. 对于取模中的除法运算,如x=(a/2) mod P可以转化成x=((a mod (2∗P))/2) mod P

Code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 70
#define LL long long
LL n,m,K,P,ans,mi[N];
inline int in(){
    int x=0; char ch=getchar(); bool f=1;
    while (ch<'0'||ch>'9'){
        if (ch=='-') f=0;
        ch=getchar();
    }while (ch>='0'&&ch<='9')
        x=x*10+ch-'0',ch=getchar();
    if (!f) x=-x; return x;
}
inline LL Lin(){
    LL x=0; char ch=getchar(); bool f=1;
    while (ch<'0'||ch>'9'){
        if (ch=='-') f=0;
        ch=getchar();
    }while (ch>='0'&&ch<='9')
        x=x*10ll+(LL)(ch-'0'),ch=getchar();
    if (!f) x=-x; return x;
}
inline LL calc(LL x,LL y){
    LL s=(((x+y)%(P*2ll))*((y-x+1)%(P*2ll)))%(P*2ll);
    s/=2ll,s%=P; return s;
}
inline LL work(LL x,LL y,int xx,int yy){
    LL s=0,z; if (xx<yy) swap(x,y),swap(xx,yy);
    x^=(x&(mi[xx]-1)),y^=(y&(mi[xx]-1)),z=x^y;
    if (z>K) s=calc(z-K,z+mi[xx]-K-1);
    else if ((z+mi[xx])>K) s=calc(0,z+mi[xx]-K-1);
    s=(s*(mi[yy]%P))%P; return s;
}
int main(){
    int T=in(),i,j,tt; LL x,y;
    mi[0]=1ll;
    for (i=1; i<=62; i++) mi[i]=mi[i-1]<<1;
    for (tt=1; tt<=T; tt++){
        n=Lin(),m=Lin(),K=Lin();
        P=Lin(),x=0ll,ans=0ll;
        for (i=62; i>=0; i--){
            if (n&mi[i]){
                y=0ll;
                for (j=62; j>=0; j--){
                    if (m&mi[j]){
                        ans=(ans+work(x,y,i,j))%P,y|=mi[j];
                    }
                }x|=mi[i];
            }
        }printf("%I64d\n",ans);
    }return 0;
}

T2
题目大意:
给出n个数,对于两个数x,y,它们能配对的条件是相差一个质因子,配对成功可以获得cx×cy,每个数有bi个可用,求在配对的价值和不小于0的情况下最多能匹配多少对。

题解:
最大费用最大流。题目中给出的是一个二分图,对其建网络流图:
S−>每个奇数个质因子的数,流量为bi,费用为0
每个奇数个质因子的数−>每个能配对的偶数个质因子的数,流量为inf,费用为ci×cj
每个偶数个质因子的数−>T,流量为bi,费用为0
然后跑最大费用流,直到某次增广后总费用为负,计算一下最后跑的流量即可。

Code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 610
#define M 600010
#define P 2000000
#define inf 1000000000
#define limit -100000000000000ll
#define LL long long
struct A{
    int x,y,k; LL z;
}a[N];
struct e{
    int u,v,cap,next; LL cost;
}e[M*2];
int n,ans=0,num=1,S,T,head[N],pre[N],flow[N],q[M*4];
bool vis[N]; LL dis[N],sum=0;
inline int in(){
    int x=0; char ch=getchar(); bool f=1;
    while (ch<'0'||ch>'9'){
        if (ch=='-') f=0;
        ch=getchar();
    }while (ch>='0'&&ch<='9')
        x=x*10+ch-'0',ch=getchar();
    if (!f) x=-x; return x;
}
inline LL Lin(){
    LL x=0; char ch=getchar(); bool f=1;
    while (ch<'0'||ch>'9'){
        if (ch=='-') f=0;
        ch=getchar();
    }while (ch>='0'&&ch<='9')
        x=x*10ll+(LL)(ch-'0'),ch=getchar();
    if (!f) x=-x; return x;
}
inline void add(int u,int v,int cap,LL cost){
    e[++num].u=u,e[num].v=v,e[num].cap=cap;
    e[num].cost=cost,e[num].next=head[u],head[u]=num;
    e[++num].u=v,e[num].v=u,e[num].cap=0;
    e[num].cost=-cost,e[num].next=head[v],head[v]=num;
}
inline void divide(int xu){
    int i,x=a[xu].x,y;
    a[xu].k=0,y=sqrt(x);
    for (i=2; i<=sqrt(x); i++){
        while (!(x%i)) x/=i,a[xu].k++;
    }if (x>1) a[xu].k++;
}
inline bool spfa(){
    int i,u,v,h=0,t=1;
    for (i=S; i<=T; i++)
        vis[i]=0,dis[i]=limit;
    LL minn=dis[0];
    q[h]=S,dis[S]=0ll,flow[S]=inf,vis[S]=1;
    while (h<t){
        u=q[h%P],h++,vis[u]=0;
        for (i=head[u]; i; i=e[i].next){
            v=e[i].v;
            if (e[i].cap>0&&dis[v]<dis[u]+e[i].cost){
                dis[v]=dis[u]+e[i].cost,pre[v]=i;
                flow[v]=min(flow[u],e[i].cap);
                if (!vis[v]) q[t%P]=v,t++,vis[v]=1;
            }
        }
    }if (dis[T]>minn) return true;
    else return false;
}
int main(){
    int i,j; n=in(),S=0,T=n+1;
    for (i=1; i<=n; i++) a[i].x=in();
    for (i=1; i<=n; i++) a[i].y=in();
    for (i=1; i<=n; i++) a[i].z=Lin();
    for (i=1; i<=n; i++){
        divide(i);
        if (a[i].k&1) add(S,i,a[i].y,0);
        else add(i,T,a[i].y,0);
    }for (i=1; i<=n; i++){
        if (a[i].k&1){
            for (j=1; j<=n; j++){
                if (i==j) continue;
                if (!(a[j].k&1)){
                    if (!(a[i].x%a[j].x)&&a[i].k==a[j].k+1)
                        add(i,j,inf,a[i].z*a[j].z);
                    if (!(a[j].x%a[i].x)&&a[j].k==a[i].k+1)
                        add(i,j,inf,a[i].z*a[j].z);
                }
            }
        }
    }while (spfa()){
        if ((sum+dis[T]*flow[T])<0){
            ans+=(int)(sum/(-dis[T])); break;
        }else {
            for (i=T; i!=S; i=e[pre[i]].u){
                e[pre[i]].cap-=flow[T];
                e[pre[i]^1].cap+=flow[T];
            }ans+=flow[T],sum+=dis[T]*flow[T];
        }
    }printf("%d\n",ans);
    return 0;
}

T3
题目大意:
给出一棵n个节点的树,每次操作选一条链,用一个自变量是和出发点的距离的一次函数更新最小值,多次询问某条链的最小值。

题解:
据说这个题是李超树,国家集训队作业题挂到了树上(听说qdez的神犇们都做过。。。)
用线段树维护覆盖当前区间的线段,更新的时候分情况讨论,如果可以更新就下传当前线段,然后标记新线段,每次线段最多被分成log(n)个区间,下放最多log(n)层,算上树链剖分,总的复杂度是O(nlog3(n))。

Code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100010
#define inf 123456789123456789ll
#define LL long long
#define root 1,1,n
#define lch rt<<1,l,mid
#define rch rt<<1|1,mid+1,r
struct E{
    int v,next; LL k;
}e[N<<1];
struct Line{
    LL k,b;
    inline LL F(LL x){
        return k*x+b;
    }
};
struct Tr{
    Line x; LL minn; bool f;
}tr[N<<2];
int n,m,num=0,tot=0,head[N],cur[N],fa[N][20],de[N],w[N],top[N],sz[N],son[N],q[N]; LL ans,dis[N],Dis[N];
inline int in(){
    int x=0; char ch=getchar(); bool f=1;
    while (ch<'0'||ch>'9'){
        if (ch=='-') f=0;
        ch=getchar();
    }while (ch>='0'&&ch<='9')
        x=x*10+ch-'0',ch=getchar();
    if (!f) x=-x; return x;
}
inline LL Lin(){
    LL x=0ll; char ch=getchar(); bool f=1;
    while (ch<'0'||ch>'9'){
        if (ch=='-') f=0;
        ch=getchar();
    }while (ch>='0'&&ch<='9')
        x=x*10ll+(LL)(ch-'0'),ch=getchar();
    if (!f) x=-x; return x;
}
inline void add(int u,int v,LL k){
    e[++num].v=v,e[num].k=k;
    e[num].next=head[u],head[u]=num;
}
inline void BFS(){
    int i,j,u,v,h=0,t=1; q[h]=1,dis[1]=0;
    for (i=1; i<=n; i++) cur[i]=head[i];
    while (h<t){
        u=q[h++];
        for (i=1; (1<<i)<=de[u]; i++)
            fa[u][i]=fa[fa[u][i-1]][i-1];
        for (i=head[u]; i; i=e[i].next){
            v=e[i].v; if (v==fa[u][0]) continue;
            fa[v][0]=u,de[v]=de[u]+1;
            dis[v]=dis[u]+e[i].k,q[t++]=v;
        }
    }for (i=t-1; i>=0; i--){
        u=q[i],sz[u]=1,son[u]=0;
        for (j=head[u]; j; j=e[j].next){
            v=e[j].v; if (v==fa[u][0]) continue;
            sz[u]+=sz[v]; if (sz[son[u]]<sz[v]) son[u]=v;
        }
    }for (i=0; i<t; i++){
        u=q[i];
        if (!w[u]){
            for (j=u; j; j=son[j])
                w[j]=++tot,Dis[tot]=dis[j],top[j]=u;
        }
    }
}
inline int lca(int x,int y){
    if (de[x]<de[y]) swap(x,y);
    int i,k=de[x]-de[y];
    for (i=18; i>=0; i--)
        if (k&(1<<i)) x=fa[x][i];
    if (x==y) return x;
    for (i=18; i>=0; i--)
        if (fa[x][i]!=fa[y][i])
            x=fa[x][i],y=fa[y][i];
    if (x==y) return x;
    return fa[x][0];
}
inline void push_up(int rt){
    tr[rt].minn=min(tr[rt].minn,min(tr[rt<<1].minn,tr[rt<<1|1].minn));
}
inline void build(int rt,int l,int r){
    tr[rt].minn=inf,tr[rt].f=0;
    if (l==r) return;
    int mid=(l+r)>>1;
    build(lch),build(rch);
    push_up(rt);
}
inline void change(int rt,int l,int r,int ll,int rr,Line x){
    if (ll<=l&&r<=rr){
        tr[rt].minn=min(tr[rt].minn,min(x.F(Dis[l]),x.F(Dis[r])));
        if (!tr[rt].f){
            tr[rt].f=1,tr[rt].x=x;
            return;
        }if (l==r){
            if (x.F(Dis[l])<tr[rt].x.F(Dis[l])) tr[rt].x=x;
            return;
        }int mid=(l+r)>>1;
        LL k1=x.F(Dis[l]),k2=tr[rt].x.F(Dis[l]);
        LL kk1=x.F(Dis[mid]),kk2=tr[rt].x.F(Dis[mid]);
        LL kkk1=x.F(Dis[r]),kkk2=tr[rt].x.F(Dis[r]);
        if (k1>k2&&kkk1>kkk2) return;
        if (k1<k2&&kkk1<kkk2){
            tr[rt].x=x; return;
        }if (kk1<kk2)
            swap(x,tr[rt].x),swap(k1,k2),swap(kkk1,kkk2);
        if (k1<k2) change(lch,ll,rr,x);
        if (kkk1<kkk2) change(rch,ll,rr,x);
        return;
    }int mid=(l+r)>>1;
    if (ll<=mid) change(lch,ll,rr,x);
    if (rr>mid) change(rch,ll,rr,x);
    push_up(rt);
}
inline LL query(int rt,int l,int r,int ll,int rr){
    if (ll<=l&&r<=rr) return tr[rt].minn;
    int mid=(l+r)>>1; LL k=inf;
    if (tr[rt].f) k=min(k,min(tr[rt].x.F(Dis[max(ll,l)]),tr[rt].x.F(Dis[min(rr,r)])));
    if (ll<=mid) k=min(k,query(lch,ll,rr));
    if (rr>mid) k=min(k,query(rch,ll,rr));
    return k;
}
inline void work_change(int x,int y,LL z,LL zz){
    int f=lca(x,y); LL k1,b1,k2,b2;
    k1=-z,b1=z*dis[x]+zz;
    k2=z,b2=z*(-2*dis[f]+dis[x])+zz;
    while (de[top[x]]>de[f]){
        change(root,w[top[x]],w[x],(Line){k1,b1});
        x=fa[top[x]][0];
    }while (de[top[y]]>de[f]){
        change(root,w[top[y]],w[y],(Line){k2,b2});
        y=fa[top[y]][0];
    }if (x!=f) change(root,w[f],w[x],(Line){k1,b1});
    else if (y!=f) change(root,w[f],w[y],(Line){k2,b2});
    else change(root,w[f],w[f],(Line){k1,b1});
}
inline void work_query(int x,int y){
    ans=inf;
    while (top[x]!=top[y]){
        if (de[top[x]]<de[top[y]]) swap(x,y);
        ans=min(ans,query(root,w[top[x]],w[x]));
        x=fa[top[x]][0];
    }if (de[x]<de[y]) swap(x,y);
    ans=min(ans,query(root,w[y],w[x]));
    printf("%lld\n",ans);
}
int main(){
    n=in(),m=in(); int i,op,x,y; LL z,zz;
    for (i=1; i<n; i++){
        x=in(),y=in(),z=Lin();
        add(x,y,z),add(y,x,z);
    }BFS(),build(root);
    for (i=1; i<=m; i++){
        op=in();
        if (op==1){
            x=in(),y=in(),z=Lin(),zz=Lin();
            work_change(x,y,z,zz);
        }else {
            x=in(),y=in();
            work_query(x,y);
        }
    }return 0;
}

Day2
T1
题目大意:
开始有一个空串,n次操作,每次在串的最后新添一个字符,每次操作完后求此时串中不同字串的个数。

题解:
SA+线段树。对原串建前缀数组,然后问题转变成了每次加入i个前缀,求有多少之前没出现过的。那就可以用线段树维护一下当前rank的前驱和后继,查一下他们之间的lcp,加加减减就好了(zkw好写好调啊)。
Ps. 据说是SAM裸题,然而我并不会啊。

Code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 200010
#define LL long long
int n,m,tot,a[N],sa[N],rank[N],cc[N],h[N],tt[N],height[N<<2],tr[N<<2]; LL ans=0;
inline int in(){
    int x=0; char ch=getchar(); bool f=1;
    while (ch<'0'||ch>'9'){
        if (ch=='-') f=0;
        ch=getchar();
    }while (ch>='0'&&ch<='9')
        x=x*10+ch-'0',ch=getchar();
    if (!f) x=-x; return x;
}
inline bool cmp(int x,int y){
    return a[x]<a[y];
}
inline void SA(){
    int i,j;
    for (i=1; i<=n; i++) sa[i]=i;
    sort(sa+1,sa+n+1,cmp);
    for (i=1,m=0; i<=n; i++){
        m++,rank[sa[i]]=m;
        while (i<n&&a[sa[i]]==a[sa[i+1]])
            i++,rank[sa[i]]=m;
    }for (j=1; j<=n&&m<n; j<<=1){
        for (i=0; i<=m; i++) cc[i]=0;
        for (i=1; i<=n; i++) cc[rank[i+j]]++;
        for (i=1; i<=m; i++) cc[i]+=cc[i-1];
        for (i=1; i<=n; i++) tt[cc[rank[i+j]]--]=i;
        for (i=0; i<=m; i++) cc[i]=0;
        for (i=1; i<=n; i++) cc[rank[i]]++;
        for (i=1; i<=m; i++) cc[i]+=cc[i-1];
        for (i=n; i>=1; i--) sa[cc[rank[tt[i]]]--]=tt[i];
        for (i=1,m=0; i<=n; i++){
            m++,tt[sa[i]]=m;
            while (i<n&&rank[sa[i]]==rank[sa[i+1]]&&rank[sa[i]+j]==rank[sa[i+1]+j])
                i++,tt[sa[i]]=m;
        }for (i=1; i<=n; i++) rank[i]=tt[i];
    }for (tot=1; tot<n+5; tot<<=1);
    for (i=1; i<=n; i++){
        if (rank[i]==1) continue;
        h[i]=max(0,h[i-1]-1),j=sa[rank[i]-1];
        while (a[i+h[i]]==a[j+h[i]]) h[i]++;
    }for (i=1; i<=n; i++) height[rank[i]+tot]=h[i];
    for (i=tot-1; i>=1; i--) height[i]=min(height[i<<1],height[i<<1|1]);
}
inline void add(int x){
    for (x=x+tot; x; x>>=1) tr[x]=1;
}
inline int Last(int x){
    for (x=x+tot; x; x>>=1)
        if ((x&1)&&tr[x^1]) break;
    for (x=x^1; x<tot;){
        x<<=1;
        if (tr[x|1]) x|=1;
    }return x-tot;
}
inline int Next(int x){
    for (x=x+tot; x; x>>=1)
        if ((!(x&1))&&tr[x^1]) break;
    for (x=x^1; x<tot;){
        x<<=1;
        if (!tr[x]) x|=1;
    }return x-tot;
}
inline int query(int l,int r){
    int s=n; l+=tot,r+=tot+1;
    for (; l^r^1; l>>=1,r>>=1){
        if (!(l&1)) s=min(s,height[l^1]);
        if (r&1) s=min(s,height[r^1]);
    }return s;
}
int main(){
    n=in(); int i,x,l,r;
    for (i=n; i>=1; i--) a[i]=in();
    SA(),add(0),add(n+1);
    for (i=n; i>=1; i--){
        ans+=(LL)(n-i+1),x=rank[i];
        l=Last(x),r=Next(x),add(x);
        if (1<=l&&r<=n) ans+=(LL)query(l,r);
        if (1<=l) ans-=(LL)query(l,x);
        if (r<=n) ans-=(LL)query(x,r);
        printf("%I64d\n",ans);
    }return 0;
}

T2
题目大意:
求长度为n的排列中恰好有k个第i位是i的方案数。

题解:
考虑f[m]表示一个长度为m排列中m个数全都不在原位的方案数,那一个长度为n(n>m)的排列中恰好有n−m个数在原位的方案是Cmn×f[m],显然f[m]=(m−1)(f[m−1]+f[m−2]),因为有取模,所以可以预处理出f[n]、1−n的阶乘和1!−n!的逆元,O(n)预处理,O(1)询问。

Code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 1000000
#define P 1000000007ll
#define LL long long
int n,m; LL fac[N+10],inv[N+10],f[N+10];
inline int in(){
    int x=0; char ch=getchar(); bool f=1;
    while (ch<'0'||ch>'9'){
        if (ch=='-') f=0;
        ch=getchar();
    }while (ch>='0'&&ch<='9')
        x=x*10+ch-'0',ch=getchar();
    if (!f) x=-x; return x;
}
inline LL C(int x,int y){
    return (((fac[x]*inv[y])%P)*inv[x-y])%P;
}
inline LL qp(LL x,LL y){
    LL z=1;
    while (y){
        if (y&1) z=(z*x)%P;
        x=(x*x)%P,y>>=1;
    }return z;
}
int main(){
    int T=in(),tt,i;
    fac[0]=1ll,f[0]=1,f[1]=0,f[2]=1;
    for (i=1; i<=N; i++)
        fac[i]=fac[i-1]*(LL)i%P;
    inv[N]=qp(fac[N],P-2);
    for (i=N-1; i>=0; i--)
        inv[i]=inv[i+1]*(LL)(i+1)%P;
    for (i=3; i<=N; i++)
        f[i]=(LL)(i-1)*(f[i-1]+f[i-2])%P;
    for (tt=1; tt<=T; tt++){
        n=in(),m=in();
        printf("%I64d\n",C(n,m)*f[n-m]%P);
    }return 0;
}

T3
题目大意:
给出n个数,划分成m块,每块的权值为块内所有数的和,设最小的方差为Ans,求Ans∗m2。

题解:
DP+斜率优化。化式子:
令xx为平均数,s[i]为前i个数的和。
Ans=1m∑mi=1(xi−xx)2
       =1m∑mi=1(x2i−2×xi×xx+xx2)
       =1m∑mi=1(x2i)−1m∑mi=1(2×xi×xx)+xx2
       =1m∑mi=1(x2i)−1m×2×s[m]×xx+xx2
       =1m∑mi=1(x2i)−2×s[m]2m2+s[m]2m2
       =1m∑mi=1(x2i)−s[m]2m2
Ans×m2=m∑mi=1x2i−s[m]2
就是求最小平方和,直接搞斜率优化就好了。

Code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 3010
#define LL long long
struct Q{
    LL x,y;
}q[N<<1];
int n,m,a[N],s[N]; LL f[N][N],ans;
inline int in(){
    int x=0; char ch=getchar(); bool f=1;
    while (ch<'0'||ch>'9'){
        if (ch=='-') f=0;
        ch=getchar();
    }while (ch>='0'&&ch<='9')
        x=x*10+ch-'0',ch=getchar();
    if (!f) x=-x; return x;
}
inline void dp(int xu){
    int i,h=1,t=1; LL x,y,x1,y1,x2,y2;
    q[h].x=(LL)s[xu-1]*2;
    q[h].y=f[xu-1][xu-1]+(LL)s[xu-1]*s[xu-1];
    for (i=xu; i<=n; i++){
        while (h<t){
            x=q[h].y-q[h].x*(LL)s[i];
            y=q[h+1].y-q[h+1].x*(LL)s[i];
            if (x>=y) h++;
            else break;
        }f[xu][i]=q[h].y-q[h].x*(LL)s[i]+(LL)s[i]*(LL)s[i];
        x=(LL)s[i]*2,y=f[xu-1][i]+(LL)s[i]*(LL)s[i];
        while (h<t){
            x1=x-q[t-1].x,y1=y-q[t-1].y;
            x2=q[t].x-q[t-1].x,y2=q[t].y-q[t-1].y;
            if (x2*y1-x1*y2<=0) t--;
            else break;
        }t++,q[t].x=x,q[t].y=y;
    }
}
int main(){
    n=in(),m=in(); int i;
    for (i=1; i<=n; i++)
        a[i]=in(),s[i]=s[i-1]+a[i];
    for (i=1; i<=n; i++)
        f[1][i]=(LL)s[i]*(LL)s[i];
    for (i=2; i<=m; i++) dp(i);
    ans=f[m][n]*(LL)m-(LL)s[n]*(LL)s[n];
    printf("%I64d\n",ans);
    return 0;
}
【省选题简易题解合集】 SDOI 2016探险路线题目所给的限制的路径实际上形状是固定的,根据形状分成三个子问题(在墙角迂回、跳跃、跨过全场洄游)进行DP,再将它们合并起来,就可以做这个题了。齿轮简单地用取模或者分解质因数来计算就可以知道是否合法了。平凡的骰子十分基础的立体几何转平面几何。转换一下坐标系随便算算投影就可以了。硬币游戏经典SG游戏,论文里面提到的经典做法,但是需要依靠一个结论就是这种硬币游戏基本都是全局的SG 阅读详情

相关推荐

字节跳动程序媛教你如何刷算法题:面试手撕代码我就没怕过

本人上一次刷题还是大一的C语言期末考试……但是面试中算法考核截止上岸前一直保持着100%正确率的光辉记录。 本文将给你指明一条刷题的决胜指南。并从算法的重要性、题库的选择以及刷题的三大步骤分别进行讲解,彻底解决你所有关于面试算法所有的困扰。

Stay Hungry Stay Foolish 求知若饥 虚心若愚 2万+

[SDOI2016Round1]解题报告

Day 1 T1: T2: 题意:给出n种数字,第i个是ai,个数是bi,权值是ci。如果ai|ajai|aj而且ai/ajai/aj是一个质数,那么这两个数字就能获得ci∗cjci*cj的价值,要求总价值不小于0的情况下求最多的配对数。 配对关系是一个二分图,所以建出费用流的图来,当跑到费用小于0的时候,处理一下当前的流量,退出就行了。 #include #include #inc

Vampire 1740

Python小白也能玩转迅投QMT量化交易?手把手教你从安装到第一个策略

本文为零基础Python用户提供了上手迅投QMT量化交易平台的完整指南。从Python 3.6环境配置、QMT客户端获取安装,到核心概念讲解,并手把手教你编写并回测一个经典的双均线交易策略,帮助初学者快速迈出量化交易的第一步。

weixin_29103191的博客 763

BestCoder Round #59 (div.2) 1001 SDOI 模拟题

问题描述 一年一度的全国信息学奥林匹克竞赛(NOI)即将举办,SD省组织进行了一次省队选拔,一共有 n (n \leq 100)n(n≤100)名选手参加了这次省队选拔。 今年,SD省的省队名额为 m (m \leq 50)m(m≤50) 人,即,今年的SD省队有 mm 名队员。 按照惯例,SD省的省队选拔有两轮比赛,依次为“Round1”和“Round2”,每个Round的满分为 30030

AC_Gibson的专栏 672

车联网ECU、TSP与TBOX通信流程

对比维度ECU(电子控制单元)BMS(电池管理系统)应用场景传统燃油车 + 新能源汽车仅限新能源汽车核心作用控制整车各系统运行管理动力电池安全与寿命车联网角色数据采集与传输的核心载体提供电池相关的核心数据。

tecoes的博客 1230

企业级AI项目落地实战指南

企业级 AI 项目落地需构建“分阶段实施 + 多维度风控”的双轮驱动体系:实施端通过 POC 验证技术可行性、试点建立评估标准、规模化实现价值复制,各阶段需结合行业案例(如东阳光药、旺盈集团)提炼可复用经验;风险端则需覆盖技术(数据安全、模型稳定性)、合规(全球监管动态)、组织(人才与文化)维度,通过工具化框架(AI TRISM)与案例策略(邮储银行可解释性设计、拓斯达培训体系)实现风险可控。最终通过“场景聚焦 - 合规嵌入 - 持续优化”的循环机制,实现 AI 技术从“试点成功”到“全面价值创造”的跨越。

2509_93209761的博客 1437

欧拉函数

1.SDOI2008仪仗队 题意:求n∗nn∗nn*n的矩阵中左下点能直接看到的点的个数 n&amp;lt;=40000n&amp;lt;=40000n(0,0)(0,0)(0,0) 那么对于同一射线上的点(x1,y1)(x1,y1)(x_1,y_1)与(x2,y2)(x2,y2)(x_2,y_2) 他们的斜率y1x1=y2x2y1x1=y2x2\frac {y_1}{x_1}=\frac{y_2}{...

YjmStr 256

比亚迪开放平台接口实战:车身状态监测与智能车联应用开发

本文详细介绍了如何利用比亚迪开放平台的车身状态接口进行智能车联应用开发。通过核心类BYDAutoBodyworkDevice,开发者可以安全获取车辆VIN、车门车窗状态、蓄电池电压、方向盘转角等实时数据,并利用监听器实现状态实时响应。文章提供了从SDK集成、接口调用到典型应用场景(如远程车况检查、车队管理)的完整实战指南,助力开发者快速构建基于比亚迪车辆数据的创新应用。

weixin_29176179的博客 713

[SDOI2016] 游戏(树链剖分+李超线段树)

题意 其中,n,m≤100000,∣a∣≤10000n,m\leq 100000,|a|\leq 10000n,m≤100000,∣a∣≤10000。 分析 设 iii 到根的距离为 disidis_idisi​。 首先化简一下式子,从 sss 到 lca(s,t)lca(s,t)lca(s,t) 路径: add=a×(diss−disi)+b=−a×disi+(b+a×diss)add=a\times (dis_s-dis_i)+b=-a\times dis_i+(b+a\times dis_s)add

hipamp的博客 366

1020空心杯电机驱动设计与ESP32实战

空心杯电机是一种高动态响应的直流微特电机,其驱动本质是解决电感负载下的大di/dt启动、反电动势耦合与电流纹波抑制问题。核心原理在于建立包含内阻、电感和反电动势的等效电路模型,并据此匹配开关器件、PWM参数与采样闭环。技术价值体现在小体积下实现毫秒级响应、低噪声(>30kHz)、高精度电流保护(±50mA)及热鲁棒性。典型应用于微型航模、手持云台与精密执行器等对功率密度和动态性能敏感的嵌入式系统。本文以1020规格空心杯电机为对象,基于ESP32平台完成从MOSFET选型、32kHz硬件PWM生成到INA2

weixin_42298164的博客 579

使用Prophet进行时间序列预测

Prophet是Facebook开发的开源时间序列预测工具,用于处理时间序列数据的建模和预测。它建立在统计模型之上,适用于多种时间序列预测问题,具有易用性和灵活性。能够处理缺失值和异常值支持对节假日和季节性的建模可以灵活地添加自定义的季节性成分自动检测变化点提供了直观的可视化工具这个简短的教程为您提供了使用Prophet进行时间序列预测的基本步骤和一些重要的概念。您可以通过阅读Prophet官方文档和其他在线资源来进一步深入学习和了解更多细节。

Mrrunsen的博客 480

SDOI2016 round1

Day1 T1 储能表 题目大意:已知n、m、k,求sigma(i=0~n-1,j=0~m-1)max((i^j)-k,0)。 思路:数位dp。fi[i][a][b][c]表示到第i位,和n、m的关系分别是a、b(0表示<,1表示=),和k的关系(0表示<,1表示=,2表示>)。 #include<iostream> #include<cstd...

weixin_30522183的博客 109

YOLO26原创自研: 魔改Bottleneck,具备多尺度和特征通道融合的结构

魔改Bottleneck,具备多尺度和特征通道融合的结构,该模型在检测准确性方面都取得了良好的效果,尤其在缺陷检测方向。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 315

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

解题思路总结

在处理数组时,有时会遇到区间处理的问题,如果这个问题无法快速合并和转移(即无法使用线段树、莫队等类似算法时),那么可以考虑数与多个数之间的影响,考虑能否进行分块并快速求出分出的每一块的贡献,进而将问题简化。数 a 异或上数 b 得到数 c ,则必有 c ≥ a 、c ≥ b ,这是有时解决异或题目非常有用的性质,比如博弈论中经典的Nim游戏的解法证明正是基于异或的这个性质。大部分树上序列(如欧拉序)都让同一子树的节点连续排列,从而使诸如线段树、莫队等的数据结构和算法可以解决树上的在线查询和修改的问题。

tjhd05151434的博客 687

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

SDOI2016 总结

4644【SDOI2016】储能表 考虑二进制下数位dpdpdp,令>k>k>k表示满足条件,计算满足条件的数个数及和 记录f[N][0/1][0/1][0/1]f[N][0/1][0/1][0/1]f[N][0/1][0/1][0/1]表示f[step][顶着n][顶着m][>k]f[step][顶着n][顶着m][>k]f[step][顶着n][顶着m][>...

qq_42835841的博客 608

SDOI

The Annual National Olympic of Information(NOI) will be held.The province of Shandong hold a Select(which we call SDOI for short) to choose some people to go to the NOI. n(n≤100)n(n≤100) people come

xinxiaxindong的博客 494

SDOI2015年题目讲解

由于有两个同学初学c++,就写几篇文章来讲真题。

AlbertHaoMing的博客 2245

[SDOI2016]排列计数(组合数+排列)

原题链接 题意:给你n个数其中这那个数的范围为1-n,如果第i个数a[i]的值为i则这个数是稳定的,那么当前给出n个数,如果恰好有m个数是稳定的,求满足序列的方案数 解法:第一步我们先选择出m个数是稳定的就是C(n,m),那么对于其他的n-m个数我们需要保证是错综排列的,对于这个错综排列的方案定义一个函数d[i],对于d[i]来说,d[i]的递推方程为d[i] = (d[i - 1] + d[i - 2])*(i - 1),那么我们求得答案就是C(n,m) * d[n-m] #include<bits

weixin_45908221的博客 190

SDOI2010 猪国杀

题目描述 《猪国杀》是一种多猪牌类回合制游戏,一共有三种角色:主猪,忠猪,反猪。每局游戏主猪有且只有一只,忠猪和反猪可以有多只,每只猪扮演一种角色。 游戏目的: 主猪(MP):自己存活的情况下消灭所有的反猪。 忠猪(ZP):不惜一切保护主猪,胜利条件与主猪相同。 反猪(FP):杀死主猪。 游戏过程: 游戏开始时候,每个玩家手里都会有4张牌,且体力上限和初始体力都是4。 开始游戏时,从主猪开始,按照...

YangHao5的博客 3807

2023SDOI游记——见证

NOIP考的不尽人意,因为自己没想出来T1后就一直在死钻T1,心态受到了不小的影响,后面的暴力也就没心思去认真打了,不过幸运的是还有一年的机会。

一个平凡的OIer,记录自己的OI生涯 386

[SDOI2010]猪国杀

好久没写博客了,就放个毒瘤的东西吧。 这题就是纯暴力的模拟。 特判一下献殷勤和表敌意。 注意无懈可以要分是对 “谁对谁献殷勤” 使用,还是 “谁对谁表敌意” 使用的。 注意只能杀下家(这是三国杀?) 其他的打tag就好了。 善用debug,不然真的会调到吐。 #include &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;algorithm&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; #include &a

DntcryBecthlev的博客 629

[SDOI2017] 天才黑客

[SDOI2017] 天才黑客 题目背景 SD0062号选手小Q同学为了偷到SDOI7012的试题,利用高超的黑客技术潜入了SDOI出题组的内联网的中央控制系统,然而这个内联网除了配备有中央控制系统,还为内联网中的每条单向网线设定了特殊的通信口令,这里通信口令是一个字符串,不同网线的口令可能不同。这让小Q同学感觉有些棘手,不过这根本难不倒他,很快他就分析出了整个内联网的结构。 题目描述 内联网中...

mekoszc的博客 1089
上一篇: SDOI2016 Round 1游记
下一篇: bzoj3956 Count 解题报告
morestep
博客等级 码龄12年 20粉丝 88原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值