• 2017.10.16 模拟赛


    题目链接

    T1

    排序后二分

    #include <algorithm>
    #include <cstdio>
    #include <cctype>
    #define N 200100
    
    using namespace std;
    inline void read(int &x)
    {
        bool f=0;register char ch=getchar();
        for(x=0;!isdigit(ch);ch=getchar()) if(ch=='-') f=1;
        for(;isdigit(ch);x=x*10+ch-'0',ch=getchar());
        x=f?-x:x;
    }
    int n,m,X[N],Y[N];
    double B[N],K[N];
    bool check(double x1,double y1,int mid)
    {
        if(K[mid]*x1+B[mid]>y1) return 0;
        return 1;
    }
    int main()
    {
        freopen("geometry.in","r",stdin);
        freopen("geometry.out","w",stdout);
        read(n);
        for(int i=1;i<=n;i++) read(X[i]);
        for(int i=1;i<=n;i++) read(Y[i]);
        sort(X+1,X+n+1);
        sort(Y+1,Y+n+1);
        for(int i=1;i<=n;i++)
        {
            B[i]=(double)Y[i];
            K[i]=-(double)Y[i]/(double)X[i];
        }
        read(m);
        for(int i=1,x,y;i<=m;i++)
        {
            read(x);read(y);
            int l=1,r=n,ans=0;
            for(int mid;l<=r;)
            {
                mid=(l+r)>>1;
                if(check(x,y,mid)) ans=mid,l=mid+1;
                else r=mid-1;
            }
            printf("%d
    ",ans);
        }
        fclose(stdin); fclose(stdout);
        return 0;
    }
    View Code

    T2

    差分约束做法

    记录前缀和S[i],i>=8时首先要满足条件 s[i]-s[i-8]>=a[i]

    0<=s[i]-s[i-1]<=b[i]

    i<8时有s[23]-s[16+i]+s[i]>=a[i]

    因为第三个式子不满足差分约束形式,可以看出s[23]有单调性,可以二分所以可以二分答案当常量处理

    Spfa负环则无解

    #include<cstring>
    #include<cstdio>
    int T,a[24],b[24],t[24],ans;
    int main()
    {
        freopen("cashier.in","r",stdin);
        freopen("cashier.out","w",stdout);
        scanf("%d",&T);
        while(T--)
        {
            memset(t,0,sizeof(t));
            for(int i=0;i<24;i++) scanf("%d",&a[i]);
            for(int i=0;i<24;i++) scanf("%d",&b[i]);
            ans=-1;
            for(int i=0;i<24;i++)
            {
                if(a[i]>t[i])
                {
                    int j=i;
                    while(a[i]>t[i])
                    {
                        if(j+7<i) break;
                        if(j==-1) break;
                        if(b[j]+t[i]>=a[i])
                        {
                            int res=a[i]-t[i];
                            b[j]=b[j]-res;
                            if(j<=16) {for(int k=j;k<=j+7;k++) t[k]+=res;} 
                            else {for(int num=1,k=j;num<=8;++num) t[k]+=res,k=(k+1)%24;}
                            ans+=res;
                            break;
                        }
                        else
                        {
                            int res=b[j];
                            b[j]=0;
                            if(j<=16) {for(int k=j;k<=j+7;k++) t[k]+=res;} 
                            else {for(int num=1,k=j;num<=8;++num) t[k]+=res,k=(k+1)%24;}  
                            ans+=res;
                            j--;
                        }
                    }
                }
            }
            if(ans==-1||ans>1000) printf("%d
    ",ans);
            else printf("%d
    ",ans+1);
        }
        fclose(stdin); fclose(stdout);
        return 0;
    }
    考场55分模拟代码
    #include <cstdio>
    #include <cstdlib>
    #include <queue>
    #define N 33
    using namespace std;
    
    struct edge
    {
        int t, n, l;
    }e[N * N];
    int h[N],tote;
    void adde(int u, int v, int l)
    {
        e[++tote].t = v;
        e[tote].l = l;
        e[tote].n = h[u];
        h[u] = tote;
        return ;
    }
    int d[N];
    bool inq[N];
    bool spfa()
    {
        queue<int> Q;
        for (int i = 0; i <= 24; i++) d[i] = -1e9, inq[i] = false;
        d[0] = 0; inq[0] = true; Q.push(0);
        while (!Q.empty())
        {
            int u = Q.front(); Q.pop(); inq[u] = false;
            if (d[u] > 1000) return false;
            for (int i = h[u]; i; i = e[i].n)
            {
                int v = e[i].t, l = e[i].l;
                if (d[v] < d[u] + l)
                {
                    d[v] = d[u] + l;
                    if (!inq[v])
                    {
                        inq[v] = true;
                        Q.push(v);
                    }
                }
            }
        }
        return true;
    }
    int a[30], b[30];
    bool solve(int ans)
    {
        for (int i = 0; i <= 24; i++) h[i] = 0;
        tote = 0;
        for (int i = 9; i <= 24; i++) adde(i - 8, i, a[i]);
        for (int i = 1; i <= 8; i++) adde(i + 16, i, a[i] - ans);
        for (int i = 1; i <= 24; i++) adde(i - 1, i, 0);
        for (int i = 1; i <= 24; i++) adde(i, i - 1, -b[i]);
        adde(0, 24, ans); adde(24, 0, -ans);
        return spfa();
    }
    int main(int argc, char ** argv)
    {
        freopen("cashier.in", "r", stdin);
        freopen("cashier.out", "w", stdout);
        int test;
        scanf("%d", &test);
        for (int i = 1; i <= test; i++)
        {
            for (int i = 1; i <= 24; i++) scanf("%d", &a[i]);
            for (int i = 1; i <= 24; i++) scanf("%d", &b[i]);
            int ans = 0;
            while (true)
            {
                if (++ans > 1000)
                {
                    ans = -1; break;
                }
                if (solve(ans)) break;
            }
            printf("%d
    ", ans);
        }
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    std

    T3

    线段树

    部分分可以dp f[i][j]表示前i个数选了j个的答案

    f[i][j]=f[i-1][j]+f[i-1][j-1]*a[i] (i选不选)

    k比较小,所以线段树每个节点维护一个区间答案记为f[i]

    考虑一段区间i,左边取j个右边就取i-j个 答案是每个方案的左边乘右边的和。

    就是i左儿子f[j]和右边的f[i-j] 所以f[i]=Σ(j=0~i) lc f[j]*rc f[i-j]

    考虑取反操作,i是奇数就取反,偶数无影响(因为是相乘)

    考虑区间加, 开始f[i] a1*a2……an  后来是(a1+c)*(a2+c)……(an+c)

    考虑类似二项式定理,当上述a1~an  n个方案如果取了j个了,分别为al1,al2……alj

    那考虑最后答案,如果已经选了j个方案是(al1+c)(al2+c)……(alj+c)再还能选i-j个 最后答案是C(len-i,i-j)*f[j]*c^(i-j)

    复杂度 O(k^2*nlogn)

    #include <algorithm>
    #include <cstdio>
    #include <cctype>
    #define Mod 1000000007
    typedef long long LL;
    #define BUF 12312312
    LL n,m,ans,z,a[50005];
    char Buf[BUF],*buf=Buf;
    inline void read(LL &x)
    {
        bool f=0;
        for(x=0;!isdigit(*buf);++buf) if(*buf=='-') f=1;
        for(;isdigit(*buf);x=x*10+*buf-'0',++buf);
        x=f?(-x):x;
    }
    void dfs(LL l,LL r,LL num,LL sc)
    {
        if(num==z)
        {
            ans=(ans+sc+Mod)%Mod;
            return;
        }
        for(int i=l;i<=r;++i) dfs(i+1,r,num+1,(sc*a[i]+Mod)%Mod);
    }
    int main(int argc,char *argv[])
    {
        freopen("game.in","r",stdin);
        freopen("game.out","w",stdout);
        fread(buf,1,BUF,stdin);
        read(n),read(m);
        if(n<=100||m<=100)
        {
            for(int i=1;i<=n;++i) read(a[i]);
            for(LL opt,x,y;m--;)
            {
                read(opt),read(x);read(y);
                if(opt==2) {for(int i=x;i<=y;++i) a[i]=-a[i];} 
                if(opt==1) {read(z);for(int i=x;i<=y;++i) a[i]=(a[i]+z+Mod)%Mod;}
                if(opt==3)
                { 
                    read(z);
                    ans=0;dfs(x,y,0,1);
                    printf("%I64d
    ",(ans+Mod)%Mod);
                }
            }
        }
        else
        {
            puts("hello ladies and gentlemen");
            puts("i'm MC bytlxmdsyl");
            puts("有一本书名叫天方夜谭");
            puts("很奇妙又好看");
            puts("叙述的是阿拉伯的故事");
            puts("到处都在流传");
            puts("由阿拉丁神灯");
            puts("有辛巴达航海");
            puts("one two three and four");
            puts("come on yo let's go");
            puts("这里有个神奇的故事");
            puts("一个人 一个人");
            puts("一个人的命运会改变");
            puts("阿里 阿里巴巴");
            puts("阿里巴巴是个快乐的青年");
            puts("阿里 阿里巴巴");
            puts("阿里巴巴是个快乐的青年");
            puts("#芝麻开门#");
        }
        fclose(stdin); fclose(stdout);
        return 0;
    }
    考场30分暴力代码
    #include <cstdio>
    #include <cstdlib>
    #define MOD 1000000007
    #define N 100005
    typedef long long LL; 
    using namespace std;
    
    struct Node
    {
        LL f[11];
    }node[N * 4];
    LL a[N], lazy1[N * 4];
    bool lazy2[N * 4];
    LL C[N][11];
    Node merge(Node lc, Node rc)
    {
        Node o;
        o.f[0] = 1;
        for (int i = 1; i <= 10; i++)
        {
            o.f[i] = 0;
            for (int j = 0; j <= i; j++)
                o.f[i] = (o.f[i] + lc.f[j] * rc.f[i - j] % MOD) % MOD;
        }
        return o;
    }
    void build(int o, int l, int r)
    {
        if (l == r)
        {
            for (int i = 0; i <= 10; i++) node[o].f[i] = 0;
            node[o].f[0] = 1;
            node[o].f[1] = (a[l] % MOD + MOD) % MOD;
            return ;
        }
        int mid = (l + r) >> 1;
        build(o * 2, l, mid);
        build(o * 2 + 1, mid + 1, r);
        node[o] = merge(node[o * 2], node[o * 2 + 1]);
        return ;
    }
    void update1(int o, int l, int r, int c)
    {
        int len = r - l + 1;
        LL ff[11];
        for (int i = 0; i <= 10; i++) ff[i] = node[o].f[i];
        for (int i = 1; i <= 10; i++)
        {
            node[o].f[i] = 0;
            LL t = 1;
            for (int j = 0; j <= i; j++)
            {
                LL tmp = ff[i - j] * C[len - (i - j)][j] % MOD * t % MOD;
                node[o].f[i] = (node[o].f[i] + tmp) % MOD;
                t = t * c % MOD;
            }
        }
        return ;
    }
    void push_down(int o, int l, int r)
    {
        int mid = (l + r) >> 1;
        if (lazy1[o])
        {
            if (lazy2[o * 2])
                lazy1[o * 2] = (lazy1[o * 2] + MOD - lazy1[o]) % MOD;
            else 
                lazy1[o * 2] = (lazy1[o * 2] + lazy1[o]) % MOD;
            if (lazy2[o * 2 + 1])
                lazy1[o * 2 + 1] = (lazy1[o * 2 + 1] + MOD - lazy1[o]) % MOD;
            else 
                lazy1[o * 2 + 1] = (lazy1[o * 2 + 1] + lazy1[o]) % MOD;
            update1(o * 2, l, mid, lazy1[o]);
            update1(o * 2 + 1, mid + 1, r, lazy1[o]);
            lazy1[o] = 0;
        }
        if (lazy2[o])
        {
            lazy2[o * 2] ^= 1;
            lazy2[o * 2 + 1] ^= 1;
            for (int j = 1; j <= 10; j += 2)
            {
                node[o * 2].f[j] = MOD - node[o * 2].f[j];
                node[o * 2 + 1].f[j] = MOD - node[o * 2 + 1].f[j];
            }
            lazy2[o] = 0;
        }
    }
    void modify1(int o, int l, int r, int ll, int rr, int c)
    {
        if (ll <= l && rr >= r)
        {
            if (lazy2[o]) lazy1[o] = (lazy1[o] + MOD - c) % MOD;
            else lazy1[o] = (lazy1[o] + c) % MOD;
            update1(o, l, r, c);
            return ;
        }
        int mid = (l + r) >> 1;
        push_down(o, l, r);
        if (ll <= mid) modify1(o * 2, l, mid, ll, rr, c);
        if (rr > mid) modify1(o * 2 + 1, mid + 1, r, ll, rr, c);
        node[o] = merge(node[o * 2], node[o * 2 + 1]);
        return ;
    }
    void modify2(int o, int l, int r, int ll, int rr)
    {
        if (ll <= l && rr >= r)
        {
            for (int i = 1; i <= 10; i += 2) node[o].f[i] = MOD - node[o].f[i];
            lazy2[o] ^= 1;
            return ;
        }
        int mid = (l + r) >> 1;
        push_down(o, l, r);
        if (ll <= mid) modify2(o * 2, l, mid, ll, rr);
        if (rr > mid) modify2(o * 2 + 1, mid + 1, r, ll, rr);
        node[o] = merge(node[o * 2], node[o * 2 + 1]);
        return ;
    }
    Node query(int o, int l, int r, int ll, int rr)
    {
        if (ll <= l && rr >= r) 
            return node[o];
        int mid = (l + r) >> 1;
        push_down(o, l, r);
        if (rr <= mid) return query(o * 2, l, mid, ll, rr);
        if (ll > mid) return query(o * 2 + 1, mid + 1, r, ll, rr);
        Node lc = query(o * 2, l, mid, ll, rr);
        Node rc = query(o * 2 + 1, mid + 1, r, ll, rr);
        return merge(lc, rc);
    }
    int main(int argc, char ** argv)
    {
        freopen("game.in", "r", stdin);
        freopen("game.out", "w", stdout);
        int n, m;
        scanf("%d %d", &n, &m);
        C[0][0] = 1;
        for (int i = 1; i <= n; i++)
        {
            C[i][0] = 1;
            for (int j = 1; j <= 10; j++) 
                C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
        }
        for (int i = 1; i <= n; i++) 
            scanf("%d", &a[i]);
        build(1, 1, n); 
        for (int i = 1; i <= m; i++)
        {
    
            int l, r, opt;
            scanf("%d%d%d",&opt, &l, &r);
            if (opt == 1)
            {
                int c;
                scanf("%d", &c);
                c = (c % MOD + MOD) % MOD;
                modify1(1, 1, n, l, r, c);
            }
            else if (opt == 2)
            {
                modify2(1, 1, n, l, r);
            }
            else
            {
                int k;
                scanf("%d", &k);
                Node o = query(1, 1, n, l, r);
                printf("%d
    ", o.f[k] % MOD);
            }
        }
        return 0;
    }
    std
  • 相关阅读:
    区块链
    区块链
    区块链
    区块链
    区块链 – 介绍
    区块链 教程
    Matplotlib 直方图
    Matplotlib 饼图
    Matplotlib 柱状图
    Matplotlib 多个图形
  • 原文地址:https://www.cnblogs.com/ruojisun/p/7678419.html
Copyright © 2020-2023  润新知