【NOIP2017】Day7

Solution

T1:
推了一个考试的数学公式,贼复杂,事实上正解也挺复杂的,什么二次函数求和?此处%ljn大佬的思路+精妙的代码,思路:6个点最多分成5的区域,注意左闭右开后枚举每个机器人在那个区间,在分类讨论1.3个在同一区间2.两个在同一区间3.在不同区间,分别计算,这个好算多了
T2:
数位DP,考试前讲过,A了,CF上的题
http://www.cnblogs.com/vongang/p/3141273.html
http://www.cnblogs.com/hxer/p/5169877.html
http://blog.csdn.net/keshuai19940722/article/details/19605745
http://blog.csdn.net/qq_33184171/article/details/52332586
贴几份吧,不想讲了
T3:
其实是水题,第一问可以直接算出各个字符数在计算,
40%:预处理字符串中各个字符的个数,计算O(N^2*62^2)
100%:预处理字符串与各个字符之间的贡献,计算O(N^2*62)

CODE

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
#define ll long long
int l[4],r[4],a[10],cnt;


double C2(double x)
{
    return x*(x-1)/2.0;
}
double C3(double x)
{
    return x*(x-1)*(x-2)/6.0;
}
int main()
{
    freopen("jump.in","r",stdin);
    freopen("jump.out","w",stdout);
    int T;
    scanf("%d",&T);
    while (T--)
    {
        cnt=0;
        double ans=0;
        for (int i=1;i<=3;i++)
        {
            scanf("%d%d",&l[i],&r[i]);
            a[++cnt]=l[i]; a[++cnt]=r[i]+1;
        }
        sort(a+1,a+1+cnt);
        cnt=unique(a+1,a+1+cnt)-a-1;
        for (int i=1;i<=cnt-1;i++)
            for (int j=1;j<=i;j++)
                for (int k=1;k<=j;k++)
                    if (l[1]<=a[i] && a[i+1]-1<=r[1] && l[2]<=a[j] && a[j+1]-1<=r[2] && l[3]<=a[k] && a[k+1]-1<=r[3])
                    {
                        double n=a[i+1]-a[i],m=a[j+1]-a[j],p=a[k+1]-a[k];
                        if (i==j && j==k)
                            ans+=C3(n)+C2(n)*2.0+(double)n;
                        else if (i!=j && j!=k && i!=k)
                            ans+=n*m*p;
                        else if (i==j)
                            ans+=C2(n)*p+n*p;
                        else if (j==k)
                            ans+=C2(m)*n+n*m;
                    }
        for (int i=1;i<=3;i++) ans/=(double)(r[i]-l[i]+1);
        printf("%.9lf\n",ans);          
    }   
    return 0;
}
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
#define ll long long
ll pow10[20],Pow[20],dp[20][2][2520][50];
int num[20],flcm[512],Map[2521],Map2[50],tot;

int gcd(int a,int b)
{
    return b==0?a:gcd(b,a%b);
}
int lcm(int a,int b)
{
    if (a==0) return b;
    else if (b==0) return a;
    else return a/gcd(a,b)*b;
}
ll solve(ll x)
{
    int len;
    ll ans=0;
    if (x==1e18) ans=1,x--;
    for (len=0;len<=18 && pow10[len]<=x;len++);
    for (int i=len;i>0;i--) num[i]=x%pow10[len-i+1]/pow10[len-i];
    memset(dp,0,sizeof(dp));
    dp[0][1][0][0]=1;
    for (int i=0;i<=len;i++)
        for (int j=0;j<2;j++)
            for (int k=0;k<2520;k++)
                for (int l=0;l<tot;l++)
                {
                    ll p=dp[i][j][k][l];
                    int pp=Map2[l];
                    if (!p) continue;
                    if (i==len) 
                    {
                        if (k % pp==0) ans+=p;
                        continue;
                    }
                    if (j==0)
                    {
                        for (int q=0;q<=9;q++)
                            dp[i+1][0][(k+q*Pow[len-i-1])%2520][Map[lcm(pp,q)]]+=p;                     
                    }
                    else
                    {
                        for (int q=0;q<num[i+1];q++)
                            dp[i+1][0][(k+q*Pow[len-i-1])%2520][Map[lcm(pp,q)]]+=p;
                        dp[i+1][1][(k+num[i+1]*Pow[len-i-1])%2520][Map[lcm(pp,num[i+1])]]+=p;
                    }               
                }
    return ans;
}
void prepare()
{
    pow10[0]=Pow[0]=1;
    for (int i=1;i<=18;i++) pow10[i]=pow10[i-1]*10,Pow[i]=pow10[i]%2520;
    for (int i=1;i<(1<<9);i++)
        for (int j=1;j<=9;j++)
            if (i & (1<<j-1))
                flcm[i]=lcm(flcm[i-(1<<j-1)],j);
    for (int i=1;i<(1<<9);i++)
        if (!Map[flcm[i]]) Map[flcm[i]]=tot++,Map2[tot-1]=flcm[i];
}
int main()
{
    freopen("number.in","r",stdin);
    freopen("number.out","w",stdout);
    prepare();
    int T;
    scanf("%d",&T);
    while (T--)
    {
        ll a,b;
        scanf("%lld%lld",&a,&b);
        printf("%lld\n",solve(b)-solve(a-1));
    }   
    return 0;
}
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
#define ll long long
#define MOD 1000000007
char str1[10],str2[10],str[1000010];
ll a[100][100],sum[1010][100],cnt[1010][100];
int n,m;

int id(char ch)
{
    if (ch>='0' && ch<='9') return ch-'0'+1;
    else if (ch>='A' && ch<='Z') return ch-'A'+11;
    else if (ch>='a' && ch<='z') return ch-'a'+37;
}
void solve()
{
    ll ans=0,ans2=0;
    for (int i=1;i<=n;i++)
        for (int j=i;j<=n;j++)
        {
            ll tot=0;
            for (int k=1;k<=62;k++)
                tot=(tot+sum[i][k]*cnt[j][k])%MOD;
            ans=(ans+tot)%MOD;
            ans2=(ans2+tot*tot)%MOD;
        }
    cout<<ans<<endl<<ans2<<endl;    
}
void ReadInfo()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++)
    {
        int x;
        scanf("%s",str1);
        scanf("%s",str2);
        scanf("%d",&x);
        int y=id(str1[0]),z=id(str2[0]);
        a[y][z]=a[z][y]=x;
    }
    for (int i=1;i<=n;i++)
    {
        scanf("%s",str+1);  
        int len=strlen(str+1);
        for (int j=1;j<=len;j++)
            cnt[i][id(str[j])]++;
        for (int j=1;j<=62;j++)
            for (int k=1;k<=62;k++)
                sum[i][j]=(sum[i][j]+cnt[i][k]*a[j][k])%MOD;
    }
}
int main()
{
    freopen("string.in","r",stdin);
    freopen("string.out","w",stdout);
    ReadInfo();
    solve();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值