• bzoj5月月赛订正


      已完成2/9(要准备中考啊QwQ)

    T1

      考虑对所有数分解质因数,其中因子>sqrt(100000)的因子最多有一个,于是我们可以暴力维护<sqrt(100000)的因子个数的前缀和。

      剩下的就是判区间里一个数出现的次数。我写了主席树。。。

      code

      

    #include <bits/stdc++.h>
    using namespace std;
    int tot,i,j,k,n,m,x,y,t,cas,prime1[70],prime2[100001],b[100001],num1[67],num2[67],tt,c[100001],s[100001][67];
    inline int read(){
        int x=0,f=1;
        char ch=getchar();
        while (ch<'0'||ch>'9'){f=ch=='-'?-f:f;ch=getchar();}
        while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
        return x*f;
    }
    inline void pre(){
        tot=0;
        for (register int i=2;i<=100000;i++)
            if (!b[i]){
                b[i]=1;prime2[i]=++tot;
                if (i<317)prime1[tot]=i,tt=tot;
                for (register int j=i;j<=100000;j+=i)b[j]=1;
            }
    }
    int rt[200001],l[3600001],r[3600001],size[3600001],num;
    inline void Build(int &rt,int L,int R){if (!rt)rt=++num;if (L==R)return;Build(l[rt],L,L+R>>1);Build(r[rt],(L+R>>1)+1,R);}
    inline void Insert(int &rt,int la,int L,int R,int v){
        if (!rt)rt=++num;
        if (L==R){size[rt]=size[la]+1;return;}
        l[rt]=l[la];r[rt]=r[la];
        int mid=L+R>>1;
        if (v<=mid){l[rt]=0;Insert(l[rt],l[la],L,mid,v);}else {r[rt]=0;Insert(r[rt],r[la],mid+1,R,v);}
    }
    inline int calc(int rt,int L,int R,int x){
        if (!rt)return 0;
        if (L==R)return size[rt];int mid=L+R>>1;
        if (x<=mid)return calc(l[rt],L,mid,x);else return calc(r[rt],mid+1,R,x);
    }
    int V[200001];
    int main(){
        cas=read();pre();
        while (cas--){
            n=read();m=read();
            for (register int i=1;i<=n;i++){
                x=read();y=x;V[i]=x;
                for (register int j=1;j<=tt;j++)s[i][j]=s[i-1][j];
                for (register int j=1;j<=tt;j++){while (x%prime1[j]==0)s[i][j]++,x/=prime1[j];if (x==1)break;}
                c[i]=x;
            }
            memset(rt,0,sizeof rt);
            memset(l,0,sizeof l);
            memset(r,0,sizeof r);
            memset(size,0,sizeof size);
            num=0;Build(rt[0],1,tot);
            for (register int i=1;i<=n;i++)Insert(rt[i],rt[i-1],1,tot,prime2[c[i]]);
            while (m--){
                int L=read(),R=read();x=read();
                memset(num1,0,sizeof num1);
                memset(num2,0,sizeof num2);
                for (register int j=1;j<=tt;j++){while (x%prime1[j]==0)x/=prime1[j],num2[j]++;if (x==1)break;}
                for (register int j=1;j<=tt;j++)num1[j]=s[R][j]-s[L-1][j];
                bool bo=1;
                for (register int j=1;j<=tt;j++)if (num1[j]<num2[j]){puts("No");bo=0;break;}
                if (!bo)continue;
                if (x==1){puts("Yes");continue;}
                if (calc(rt[R],1,tot,prime2[x])-calc(rt[L-1],1,tot,prime2[x])<1)puts("No");else puts("Yes");
            }
        }
        return 0;
    }
    T1

    T2

      考虑DP,f[i][j][x][y]表示走到i,j,并且路径上有x个没选,并在前i-1行以及第i行前j-1个里选了y个的最优值。ans显然等于max(f[n][m][i][i])0<=i<=t

      然后转移。

      f[i][j][x][y]可以直接转移到f[i][j+1][x][y]以及f[i][j+1][x+1][y](i,j+1不选)

      再考虑往下转移,(i+1,j)也可以选或不选,然后,再在(i,j+1)~(i,m)以及(i+1,1)~(i+1,j-1)中选最大的k个,转移给f[i+1][j][x+(1 or 0)][y+k]

      code

    #pragma GCC optimize(2)
    #include <bits/stdc++.h>
    #define RI register int
    using namespace std;
    typedef long long ll;
    int i,j,k,n,m,x,y,t,T,b[51][51][51];
    ll f[51][51][21][21],a[51][51];
    int read(){
        int x=0,f=1;
        char ch=getchar();
        while (ch<'0'||ch>'9'){f=ch=='-'?-f:f;ch=getchar();}
        while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
        return x*f;
    }
    inline int max(int x,int y){return x>y?x:y;}
    int main(){
        T=read();
        while (T--){
            n=read();m=read();x=read();
            for (RI i=1;i<=n;i++)for (RI j=1;j<=m;j++)scanf("%lld",&a[i][j]);;
            memset(b,0,sizeof b);
            for (RI i=1;i<n;i++)
                for (RI j=1;j<=m;j++){
                    for (RI k=j+1;k<=m;k++)b[i][j][++b[i][j][0]]=a[i][k];
                    for (RI k=1;k<j;k++)b[i][j][++b[i][j][0]]=a[i+1][k];
                    sort(b[i][j]+1,b[i][j]+1+b[i][j][0]);
                }
            memset(f,-1,sizeof f);
            f[1][1][0][0]=a[1][1];f[1][1][1][0]=0;
            for (RI i=1;i<=n;i++)
                for (RI j=1;j<=m;j++)
                    for (RI k=0;k<=x;k++)
                        for (RI t=0;t<=x;t++)
                            if (f[i][j][k][t]>-1){
                                if (j<=m){
                                    f[i][j+1][k][t]=max(f[i][j+1][k][t],f[i][j][k][t]+a[i][j+1]);
                                    if (k<x)f[i][j+1][k+1][t]=max(f[i][j+1][k+1][t],f[i][j][k][t]);
                                }
                                if (i<n){
                                    ll p=0;
                                    for (RI h1=0;h1+t<=x;h1++){
                                        p+=b[i][j][b[i][j][0]-h1+1];
                                        f[i+1][j][k][t+h1]=max(f[i+1][j][k][t+h1],f[i][j][k][t]+p+a[i+1][j]);
                                        if (k<x){f[i+1][j][k+1][t+h1]=max(f[i+1][j][k+1][t+h1],f[i][j][k][t]+p);}
                                    }
                                }
                            }
            ll ans=0;for (RI i=0;i<=x;i++)ans=max(ans,f[n][m][i][i]);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    T2
  • 相关阅读:
    mongodb的CRUD操作三
    mongodb的CRUD操作二查询
    mongodb的CRUD操作一
    python 全栈Day01 安装python
    sqlalchemy 无法显示中文的问题
    2017python学习的第九天,进程,线程协程
    2017python学习的第八天,socket的使用
    2017python学习的第七天,面向对象编程
    2017python学习的第六天,面向对象
    创建证书
  • 原文地址:https://www.cnblogs.com/Acheing/p/9099260.html
Copyright © 2020-2023  润新知