2018,10,19模拟赛

jz的题...写炸了不少暴力...还有容斥等不太熟练

T1以为n^2*m过不去,想了好久

归根到底还是我太蒻了qwq

存一下代码

t1

为了稳一点写了部分分...还没删,可以自行跳过ovo

 

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=50010;
int n,m,l,r,mp[35][M],sum[35][M],cnt,rr,flg1,flg0;
long long ans;
char c[M];
int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    scanf("%d%d",&n,&m);
    rr=n*m;
    for(int i=1;i<=n;i++)
    {
        scanf("%s",c+1);
        for(int j=1;j<=m;j++)
        {
            mp[i][j]=c[j]-'0';
            if(mp[i][j]==1)
                flg1=1;
            else
                flg0=1;
        }    
    }
    scanf("%d%d",&l,&r);
    if(flg1==0)
    {
        if(l>0)
        {
            printf("0");
        }
        else
        {
            for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                ans=ans+i*j;
            printf("%lld",ans);
        }
    }
    else if(l==0&&r==n*m)
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                ans=ans+i*j;
        printf("%lld",ans);
    }
    else
    {

        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                sum[i][j]=sum[i-1][j]+sum[i][j-1]+mp[i][j]-sum[i-1][j-1];
        for(int k=1;k<=n;k++)
            for(int i=k;i<=n;i++)
            {
                int lp,rp,xx=i-k;
                lp=rp=0;
                for(int j=1;j<=m;j++)
                {
                    while(sum[i][j]-sum[xx][j]-sum[i][lp]+sum[xx][lp]>r&&lp<j)
                        lp++;
                    while(sum[i][j]-sum[xx][j]-sum[i][rp]+sum[xx][rp]>=l&&rp<j)
                        rp++;
                    ans=ans+rp-lp;
                }
            }
        printf("%lld",ans);
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

t2

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=1e5+10;
const long long mod=1e9+7;
int n,m,cnt[25][M],sum[M];
long long ans;
int main()
{
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
    scanf("%d%d",&n,&m);
    int x; 
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=m;++j)
            scanf("%d",&x),cnt[i][x]++;
    }
    for(register int nw=1;nw<=n;++nw)
        for(register int i=1;i<M;++i)
            for(register int j=i+i;j<M;j+=i)
                (cnt[nw][i]+=cnt[nw][j])%=mod;        //处理出gcd为i倍数的个数
    for(int i=1;i<M;++i)
    {
        sum[i]=1;
        for(int j=1;j<=n;++j)
            sum[i]=(long long)sum[i]*(cnt[j][i]+1)%mod;    //处理最后gcd为i的子集方案数 
        sum[i]=(sum[i]+mod-1)%mod;
    } 
    for(int i=M-10;i;--i)
        for(int j=i+i;j<M;j+=i)
            sum[i]=(sum[i]+mod-sum[j])%mod;                        
    //倒着容斥一下 (这样在更新i时j已经被容斥过了,已经是最终gcd为j的倍数了 
    for(int i=M-10;i;--i)
        ans=(ans+(long long)sum[i]*i)%mod;
    printf("%lld",ans);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

t3等填坑吧,可能咕咕咕

posted @ 2018-10-19 17:18  X_stream  阅读(157)  评论(0编辑  收藏  举报