码迷,mamicode.com
首页 > 其他好文 > 详细

20150302模拟赛

时间:2015-03-02 22:21:09      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:

T1

题目大意:我们有一个图和一些有向边,要求补无数条边使得其满足以下条件:1)i能到之后的所有点;2)边的终点比起点大;3)两点间最多一条边;4)如果j-i<=k,i到j的最短距离为j-i;5)如果j-i>k,i到j的最短距离为j-i或者j-i-k;

思路:考试的时候没有想出正解,不过想到了i只能向i+1或i+k+1连边,但是没有深入的展开。其实读完题目,应该得到的信息有:1)一定有i~i+1这条边,保证要求中的1);2)对于一个点,只能在向i+k+1连边;3)我们连的边一定在一个长度为k+1的区间内,否则就不满足最短距离的要求了,也就是所有的i~i+k+1的边都是相交的。然后就是进行穷举,找到所有可行的区间。

不过要注意以下问题:1)读入的时候如果一条边不满足j-i==1||j-i==k+1的条件,就要无解;2)如果读入的i~i+k+1的边中,有不相交的,也无解;3)在增加答案的时候,只增加之前没有的,也就是说,我们每次都要有一条之前没用过的新边,因为按起点区间的右端点枚举的,所以每一个区间的右端点一定没用过,一定要用到,所有就有了程序中注释的地方的神奇写法。

技术分享
#include<iostream>
#include<cstdio>
#define p 1000000007LL
using namespace std;
int mi[1000001]={0},sum[1000001]={0},s[1000001]={0},e[1000001]={0};
int main()
{
    freopen("olya.in","r",stdin);
    freopen("olya.out","w",stdout);
    
    int i,j,n,m,k,st,en,ans=0,mst,men;
    bool f;
    f=true;mi[0]=1;mst=0;men=1000001;
    for (i=1;i<=1000000;++i) mi[i]=(mi[i-1]<<1)%p;
    scanf("%d%d%d",&n,&m,&k);
    for (i=1;i<=m;++i)
    {
        scanf("%d%d",&st,&en);
        if (en-st!=1&&en-st!=k+1)
        {
          f=false;break;
        }
        if (en-st==k+1)
        {
          mst=max(st,mst);men=min(men,en);
          s[st]=1;e[en]=1;
        }
    }
    for (i=1;i<=n;++i) sum[i]=sum[i-1]+s[i];
    if (mst>=men) f=false;
    if (f)
    {
        if (n<=k+1) ans=1;
        else
        {
            ans=1;
            for (j=max(1,mst);j<=n-k-1;++j)
            {
                if (e[j]) break;
                i=max(1,j-k);
                ans=(ans+mi[j-i-(sum[j-1]-sum[i-1])]-s[j])%p;//一定要选至少一条新边,所以我们一定要选j为起点的边,
                                                             //但如果本来就有以j为起点的边,那么我们就把只选j的删去。 
                if (j-k+1>0&&s[j-k+1]>0) break;
            }
        }
    }
    if (!f) printf("0\n");
    else printf("%d\n",ans);
    
    fclose(stdin);
    fclose(stdout);
}
View Code

 

T2

题目大意:一个神奇的矩阵,然后某个子矩阵中元素的和。

(矩阵如下(只列举前16个元素):1   2    5    10                                    

                                              4   3   6     11

                                              9   8   7     12                                      

                                             16  15  14   13 )

思路:考试的时候,只想了60分算法,就是穷举给定矩阵的列,然后根据各种神奇的求和公式求出这一列的和,然后相加。但是,宏定义中没有在1000000007后加LL,导致。(bei)。(ju)。(le)。满分算法其实用到了很简单的思路,用四个以(1,1)为左上角的矩形的和表示这个给定的矩形,而每个以(1,1)为左上角的矩形都可以表示为一个正方形(1~n^2)和一个矩形,这个矩形又很有特点(各种等差。。。),这样我们的o(1)算法就诞生了,各种神奇的公式。可能用到高精度,来处理过大的问题,不过貌似long double也可以。。。

(比较。。。所以就没有写满分的,放个60分的。。。)

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
#define ri 10000000000LL
using namespace std;
long long fh[10001]={0},f[10001]={0},shu[100]={0};
int main()
{
    freopen("matrix.in","r",stdin);
    freopen("matrix.out","w",stdout);
    
    int x1,y1,x2,y2,t,i,j,z;
    long long ans,xx;
    for (i=1;i<=10000;++i)
    {
        f[i]=i*i;
        fh[i]=fh[i-1]+f[i];
    }
    scanf("%d",&t);
    while(t)
    {
        ans=0;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        for (i=y1;i<=y2;++i)
        {
            if (x2<=i)
            {
               ans+=(x2-x1+1)*(2*f[i-1]+x1+x2)/2;
            }
            else
            {
                if (x1<=i)
                {
                  z=x2-i;
                  xx=(long long)z;
                  ans+=((2*f[i-1]+(x1+i))*(i-x1+1)/2+xx*f[i-1]+xx*i+(1+xx)*xx*i+fh[z]);
                }
                else
                {
                    z=x2-x1+1;
                    xx=(long long)z;
                    ans+=xx*f[i-1]+xx*i+(x1-i+x2-i)*xx*i+fh[x2-i]-fh[x1-i-1];
                }
            }
        }
        if (ans/ri>0)
        {
            printf("...");
            ans%=ri;
            memset(shu,0,sizeof(shu));j=0;
            while(ans)
            {
                ++j;shu[j]=ans%10;
                ans/=10;
            }
            for (i=10;i>=1;--i) printf("%I64d",shu[i]);
            printf("\n");
        }
        else printf("%I64d\n",ans);
        --t;
    }
    
    fclose(stdin);
    fclose(stdout);
}
View Code

 

             

 

20150302模拟赛

标签:

原文地址:http://www.cnblogs.com/Rivendell/p/4309683.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!