Wannafly挑战赛18

https://www.nowcoder.com/acm/contest/129#question
A.序列(组合数学)
-2和0.5一样多,且都为偶数,枚举一下具体个数就好了
O(n) O ( n )
考时ZZ了,不会跳了过去…很久以后才A掉gg
B.随机数(矩阵快速幂)
设f[i]表示前i个数有奇数个1的概率,则
f[i+1]=f[i](1p)+(1f[i])p f [ i + 1 ] = f [ i ] ∗ ( 1 − p ) + ( 1 − f [ i ] ) ∗ p
f[i+1]=(12p)f[i]+p f [ i + 1 ] = ( 1 − 2 p ) f [ i ] + p
递推式,可以写成矩阵的形式,然后矩阵快速幂,不过要以10为底。(我zz的想不出怎么快速的把大数变成2进制,其实直接10进制快速幂不就好了吗,zz死)
复杂度 O(log10n10) O ( l o g 10 n ∗ 10 )
C.异或和(概率与期望,数学)
曼哈顿距离,每一维分开统计一下就好了。 O(nm) O ( n m )
D.网格图(dp,计数)
直接暴力dp,f[i][j][k][5]表示恰好k时间到(i,j),方向为*的方案数。
我还分开讨论了一下来转移qaq不过好像根本不用 O(nmk) O ( n m k )

E.极差
考虑枚举右端点,线段树叶子维护左端点为l时的答案(设三个序列的区间极差分别为x[0/1/2],答案就是x[0]*x[1]*x[2]),线段树维护一个区间的左端点的答案和。

我们对每个序列用两个单调栈来处理最小/大值变化的情况,显然每次弹栈时是对于这个序列的极差值的一个区间加操作,那么怎么维护答案呢?我们考虑维护所有子集和,这样就可以维护了。

复杂度 O(nlogn323) O ( n l o g n ∗ 3 ∗ 2 3 )

A

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 1010
#define mod 1000000007
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int n,C[N][N],ans=0;
inline void inc(int &x,int y){x+=y;x%=mod;}
int main(){
//  freopen("a.in","r",stdin);
    n=read()-1;
    for(int i=0;i<=n;++i) C[i][0]=1;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=i;++j)
            C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
    for(int i=0;i*4<=n;++i)
        inc(ans,(ll)C[n][2*i]*C[n-2*i][2*i]%mod);
    printf("%d\n",ans);
    return 0;
}

B

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 1000010
#define mod 1000000007
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
inline int ksm(int x,int k){
    int res=1;for(;k;k>>=1,x=(ll)x*x%mod) if(k&1) res=(ll)res*x%mod;return res;
}
char s[N];
int n,a[N];
struct Icefox{
    int x,y;
    Icefox(int _x,int _y){x=_x;y=_y;}
    friend Icefox operator*(Icefox a,Icefox b){return Icefox((ll)a.x*b.x%mod,((ll)a.x*b.y%mod+a.y)%mod);}
};
int main(){
//  freopen("a.in","r",stdin);
    int p=read();p=(ll)p*ksm(10000,mod-2)%mod;
    scanf("%s",s+1);n=strlen(s+1);
    Icefox x=Icefox(((1-2*p)%mod+mod)%mod,p),res=Icefox(1,0);
    for(int i=n;i>=1;--i){
        for(int j=1;j<=s[i]-'0';++j) res=res*x;
        Icefox tmp=x;
        for(int i=1;i<=9;++i) x=x*tmp;
    }printf("%d\n",res.y);
    return 0;
}

C

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 2010
#define mod 1000000007
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int n,m,s1[N],s2[N],tot,f1[N],f2[N],ans=0;
char s[N];
inline void inc(int &x,int y){x+=y;x%=mod;}
inline int ksm(int x,int k){
    int res=1;for(;k;k>>=1,x=(ll)x*x%mod) if(k&1) res=(ll)res*x%mod;return res;
}
int main(){
//  freopen("a.in","r",stdin);
    n=read();m=read();
    for(int i=1;i<=n;++i){
        scanf("%s",s+1);
        for(int j=1;j<=m;++j){
            if(s[j]=='0') continue;
            s1[i]++;s2[j]++;++tot;
        }
    }for(int i=2;i<=n;++i) inc(f1[1],(i-1)*s1[i]);
    int tmp=s1[1];
    for(int i=2;i<=n;++i){
        f1[i]=f1[i-1]-(tot-tmp)+tmp;f1[i]=(f1[i]%mod+mod)%mod;
        tmp+=s1[i];
    }for(int i=2;i<=m;++i) inc(f2[1],(i-1)*s2[i]);
    tmp=s2[1];
    for(int i=2;i<=m;++i){
        f2[i]=f2[i-1]-(tot-tmp)+tmp;f2[i]=(f2[i]%mod+mod)%mod;
        tmp+=s2[i];
    }tot=ksm(tot,mod-2);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j){
            ans^=(ll)(f1[i]+f2[j])*tot%mod;
        }printf("%d\n",ans);
    return 0;
}

D

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 1000010
#define mod 1000000007
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int n,m,t,f[2][210][210][5],dx[]={0,0,0,1,-1},dy[]={0,1,-1,0,0},ans=0;
inline void inc(int &x,int y){x+=y;if(x>=mod) x-=mod;}
int main(){
//  freopen("a.in","r",stdin);
    n=read();m=read();t=read();
    int x1=read(),y1=read(),D=read(),x2=read(),y2=read();
    int p=0;f[p][1][1][0]=1;
    for(int ii=1;ii<=t;++ii){
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j){
                if(abs(x1-i)<=D&&abs(y1-j)<=D){
                    if(f[p][i][j][0]){
                        for(int k=0;k<=4;++k){
                            int xx=i+dx[k],yy=j+dy[k];
                            if(xx<1||xx>n||yy<1||yy>m) continue;
                            inc(f[p^1][xx][yy][k],f[p][i][j][0]);
                        }f[p][i][j][0]=0;
                    }for(int k=1;k<=4;++k){
                        if(!f[p][i][j][k]) continue;
                        int res=f[p][i][j][k];f[p][i][j][k]=0;
                        inc(f[p^1][i][j][0],res);
                        int xx=i+dx[k],yy=j+dy[k];
                        if(xx<1||xx>n||yy<1||yy>m) continue;
                        inc(f[p^1][xx][yy][k],res);
                    }
                }else{
                    int res=0;
                    for(int k=0;k<=4;++k) inc(res,f[p][i][j][k]),f[p][i][j][k]=0;
                    if(!res) continue;
                    for(int k=0;k<=4;++k){
                        int xx=i+dx[k],yy=j+dy[k];
                        if(xx<1||xx>n||yy<1||yy>m) continue;
                        inc(f[p^1][xx][yy][k],res);
                    }
                }
            }p^=1;
    }for(int k=0;k<=4;++k) inc(ans,f[p][x2][y2][k]);
    printf("%d\n",ans);
    return 0;
}

E

#include <bits/stdc++.h>
using namespace std;
#define uint unsigned int
#define inf 0x3f3f3f3f
#define N 100010
#define mod 1000000007
inline char gc(){
    static char buf[1<<16],*S,*T;
    if(S==T){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0,f=1;char ch=gc();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=gc();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
    return x*f;
}
int n;uint ans=0;
struct node{
    uint x[8],tag[3];
}tr[N<<2];
inline void pushup(int p){
    for(int i=0;i<8;++i) tr[p].x[i]=tr[p<<1].x[i]+tr[p<<1|1].x[i];
}
inline void doadd(int p,int x,uint val){
    tr[p].tag[x]+=val;
    for(int i=0;i<8;++i) if(i>>x&1) tr[p].x[i]+=tr[p].x[i^(1<<x)]*val;
}
inline void pushdown(int p){
    for(int i=0;i<3;++i){
        if(!tr[p].tag[i]) continue;
        doadd(p<<1,i,tr[p].tag[i]);doadd(p<<1|1,i,tr[p].tag[i]);tr[p].tag[i]=0;
    }
}
inline void build(int p,int l,int r){
    if(l==r){tr[p].x[0]=1;return;}
    int mid=l+r>>1;
    build(p<<1,l,mid);build(p<<1|1,mid+1,r);pushup(p);
}
inline void add(int p,int l,int r,int x,int y,uint val,int op){
    if(x<=l&&r<=y){doadd(p,op,val);return;}
    int mid=l+r>>1;pushdown(p);
    if(x<=mid) add(p<<1,l,mid,x,y,val,op);
    if(y>mid) add(p<<1|1,mid+1,r,x,y,val,op);
    pushup(p);
}
struct seq{
    int a[N],qq1[N],qq2[N],top1,top2;
    inline void init(){
        for(int i=1;i<=n;++i) a[i]=read();top1=top2=0;
    }inline void ins(int i,int op){
        while(top1&&a[qq1[top1]]<=a[i]) add(1,1,n,qq1[top1-1]+1,qq1[top1],a[i]-a[qq1[top1]],op),--top1;
        qq1[++top1]=i;
        while(top2&&a[qq2[top2]]>=a[i]) add(1,1,n,qq2[top2-1]+1,qq2[top2],a[qq2[top2]]-a[i],op),--top2;
        qq2[++top2]=i;
    }
}a[3];
int main(){
//  freopen("a.in","r",stdin);
    n=read();build(1,1,n);
    for(int i=0;i<3;++i) a[i].init();
    for(int i=1;i<=n;++i){
        for(int j=0;j<3;++j) a[j].ins(i,j);ans+=tr[1].x[7];
    }printf("%u",ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值