• Wannafly挑战赛5


    A.珂朵莉与宇宙

    题意

    给你一个长为n的序列a,有n*(n+1)/2个子区间,问这些子区间里面和为完全平方数的子区间个数(1 <= n <= 100000,0 <= ai <= 10

    分析

    前缀和+标记

    石乐志啊最近,这么辣鸡的题都卡了一下,直接前缀和count一下,这个数据范围一看就像emmmm

    经典的sum[0]=1,这个是为了全选(1到当前位置全选)的时候,还有的是先统计在更新(有时间在撕烤一下)

    时间复杂度小于O(n*1000)

    #include<bits/stdc++.h>
    const int mod = 1e9+7;
    const int maxn = 1e5+5;
    const double EPS = 1e-6;
    using namespace std;
    int fac[maxn];
    int n;
    int a[maxn];
    int sum[maxn*10+10];
    
    int main()
    {
    
        scanf("%d", &n);
        int allsum=0;
        ll ok=0;
        sum[0]++;
        for(int i=1;i<=n;i++)
        {
            scanf("%d", &a[i]);
            allsum+=a[i];
            for(int j=0;j<=1000;j++)
            {
                if(allsum<j*j)
                    break;
                ok=ok+1ll*sum[allsum-j*j];
            }
            sum[allsum]++;
        }
        printf("%lld
    ", ok);
        return 0;
    
    }
    View Code

    B.可编程拖拉机比赛

    签到


    C.标准差

    题意

    n个点m条边的有向图,边上有边权we,你需要找到一条1到n的路径使得经过的边的标准差最小(n<=30,m<=100,w<=100)
    x1,x2,...,xk的标准差计算方法如下:
     设
    则标准差
    note:这条路径不一定要是简单路径
    分析
    这道题很可做啊,首先看出数据范围很小,暴力搜索即可
    环的问题:不难想出,一个环如果对答案有正贡献,则走无数次这个环,最终答案也就可以看做这个环的标准差。
    如何找环:BF算法可以找,但dfs直接可以找,根据dfs序对dfs上的点编号,一个点如果找到两次,肯定有环,dfs的时候再根据dfs序把边权赋给节点即可
    !!需要注意的是一个点可能在多个环上,每次遍历完当前节点的所有点,这个点要重新蛇者为未标记,重新标号。
    时间复杂度O() ?? // 不太会算啊QAQ,感觉很低的样子
    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 200;
    
    int num[maxn], vis[maxn];
    int cnt, head[maxn*2];
    double answer=0x3f3f3f3f*1.0;
    int n,m,u,v,w;
    
    struct node
    {
        int nnext,to,w;
    }edge[maxn];
    
    void addedge(int u, int v, int w)
    {
        ++cnt;
        edge[cnt].to=v;
        edge[cnt].nnext=head[u];
        edge[cnt].w=w;
        head[u]=cnt;
    }
    
    double getfc(int l, int r)
    {
        double sum=0;
        double allsum=0,ans1=0;
        for(int i=l; i<=r;i++)
        {
            allsum+=num[i];
        }
        allsum=allsum/(1.0*(r-l+1));
        for(int i=l;i<=r;i++)
        {
            ans1+=(num[i]-allsum)*(num[i]-allsum);
        }
        ans1=ans1/(1.0*(r-l+1));
        return ans1;
    }
    
    void dfs(int point, int id)
    {
        vis[point]=id;
        for(int i=head[point]; i!=0; i=edge[i].nnext)
        {
            int v=edge[i].to;
            num[id]=edge[i].w;
            if(vis[v]) answer=min(answer, getfc(vis[v], id));
            else if(v==n) answer=min(answer,getfc(1,id));
            else dfs(v,id+1);
        }
        vis[point]=0;
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d", &u, &v, &w);
            addedge(u,v,w);
        }
        dfs(1,1);
        answer=sqrt(answer);
        printf("%.6f
    ", answer);
        return 0;
    }
    View Code

    D.子序列

    题意

    给定一个小写字母字符串T,问有多少长度为m的小写字母字符串S满足,T是S的一个子序列(不需要连续)

    分析

    组合数学

    枚举最后一个字符的位置,分别考虑左右两边的情况,统计下即可

    时间复杂度O(m*sqrt(幂))

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    const int maxn = 1e5+10;
    const ll mod = 1e9+7;
    
    long long sum, zuo, you;
    ll fac[maxn];
    ll t,m;
    char s[maxn];
    
    ll qpow(ll a, ll b)
    {
        ll ans=1;
        while(b)
        {
            if(b&1)
            {
                ans*=a;
                ans%=mod;
            }
            a*=a, a%=mod;
            b>>=1;
        }
        return ans;
    }
    
    ll C(ll a,ll b)
    {
        return fac[a]*qpow(fac[b]%mod*fac[a-b]%mod, mod-2)%mod;
    }
    
    int main()
    {
        fac[0]=1;
        fac[1]=1;
        for(int i=2;i<=100000;i++)
            fac[i]=fac[i-1]*i, fac[i]%=mod;
        scanf("%s%lld", s, &m);
        ll zuo=1, you=1, sum=0;
        ll length=strlen(s);
        for(int i=length+1;i<=m;i++)
        {
            you*=26;you%=mod;
        }
        for(int i=length;i<=m;i++)
        {
            sum=C(i-1,length-1)*zuo%mod*you%mod+sum%mod;
            sum%=mod;
            zuo*=25, zuo%=mod;
            you*=qpow(26,mod-2);
            you%=mod;
           // cout<<sum<<endl;
        }
        printf("%lld
    ", sum);
        return 0;
    }
    View Code
     
    要么优秀要么生锈
  • 相关阅读:
    济南学习 Day2 T1 am
    济南学习 Day1 T2 pm
    济南学习 Day1 T3 am
    济南学习 Day 1 T2 am
    洛谷 P1209 修理牛棚== Codevs 2079 修理牛棚
    2016.10.30 济南学习 Day2 下午 T1
    餐厅随笔----2016.10.30 于济南 外出学习
    bzoj1671 [Usaco2005 Dec]Knights of Ni 骑士
    bzoj1088 [SCOI2005]扫雷Mine
    bzoj1655 [Usaco2006 Jan] Dollar Dayz 奶牛商店
  • 原文地址:https://www.cnblogs.com/Superwalker/p/8006989.html
Copyright © 2020-2023  润新知