HDU 2254 - 奥运

先离散化,然后套等比数列二分求和

二分的离散化会有问题,没出现过的数字可能定位在数组中部,就是和已出现过的数字占用同一编号,故可以先判断数字有无出现过

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <map>
  6 using namespace std;
  7 #define LL long long
  8 const int mod=2008;
  9 struct P{
 10     int a[35][35];
 11 }s,c,c1,z;
 12 int n,k,ans;
 13 LL a[100],a1[100],a2[100],p1,p2,t1,t2;
 14 map<LL,bool> flag;
 15 int cnt,size;
 16 P mult(P a,P b)
 17 {
 18     P c;
 19     for(int i=1;i<=size;i++)
 20         for(int j=1;j<=size;j++)
 21         {
 22             c.a[i][j]=0;
 23             for(int k=1;k<=size;k++)
 24                 c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%mod;
 25         }
 26     return c;
 27 }
 28 P fuc(P s,LL p)
 29 {
 30     P c=c1;
 31     while(p)
 32     {
 33         if(p&1) c=mult(c,s);
 34         s=mult(s,s);
 35         p>>=1;
 36     }
 37     return c;
 38 }
 39 P add(P a,P b)
 40 {
 41     P c;
 42     for(int i=1;i<=size;i++)
 43         for(int j=1;j<=size;j++)
 44             c.a[i][j]=(a.a[i][j]+b.a[i][j])%mod;
 45     return c;
 46 }
 47 P sum(P a,int k)
 48 {
 49     if(k==1) return a;
 50     P t = sum(a,k/2);
 51     if(k&1)
 52     {
 53         P cur = fuc(a,k/2+1);
 54         t = add(t,mult(t,cur));
 55         t = add(t,cur);
 56     }
 57     else
 58     {
 59         P cur = fuc(a,k/2);
 60         t = add(t,mult(t,cur));
 61     }
 62     return t;
 63 }
 64 void ini()
 65 {
 66     sort(a,a+cnt);
 67     size=unique(a,a+cnt)-a;
 68     memset(s.a,0,sizeof(s.a));
 69     for(int i=0;i<n;i++)
 70     {
 71         a1[i]=lower_bound(a,a+size,a1[i])-a+1;
 72         a2[i]=lower_bound(a,a+size,a2[i])-a+1;
 73         s.a[a1[i]][a2[i]]++;
 74     }
 75     memset(c1.a,0,sizeof(c1.a));
 76     for(int i=1;i<=size;i++) c1.a[i][i]=1;
 77     memset(z.a,0,sizeof(z.a));
 78 }
 79 int main()
 80 {
 81     while(~scanf("%d",&n))
 82     {
 83         flag.clear();
 84         cnt=0;
 85         for(int i=0;i<n;i++)
 86         {
 87             scanf("%lld%lld",&p1,&p2);
 88             a[cnt++]=a1[i]=p1;
 89             a[cnt++]=a2[i]=p2;
 90             flag[p1]=1;
 91             flag[p2]=1;
 92         }
 93         ini();
 94         scanf("%d",&k);
 95         while(k--)
 96         {
 97             scanf("%lld%lld%lld%lld",&p1,&p2,&t1,&t2);
 98             if(!flag[p1]||!flag[p2]) ans=0;
 99             else
100             {
101                 if(t1>t2) swap(t1,t2);
102                 P s1,s2;
103                 if(t1==0||t1==1) s1=z; else s1=sum(s,t1-1);
104                 if(t2==0) s2=z; else s2=sum(s,t2);
105                 p1=lower_bound(a,a+size,p1)-a+1;
106                 p2=lower_bound(a,a+size,p2)-a+1;
107                 ans=(s2.a[p1][p2]-s1.a[p1][p2])%mod;
108             }
109             while(ans<0) ans+=mod;
110             printf("%d\n",ans);
111         }
112     }
113 }
时间: 2024-10-10 06:10:11

HDU 2254 - 奥运的相关文章

HDU 2254 奥运(矩阵快速幂+二分等比序列求和)

HDU 2254 奥运(矩阵快速幂+二分等比序列求和) ACM 题目地址:HDU 2254 奥运 题意: 中问题不解释. 分析: 根据floyd的算法,矩阵的k次方表示这个矩阵走了k步. 所以k天后就算矩阵的k次方. 这样就变成:初始矩阵的^[t1,t2]这个区间内的v[v1][v2]的和. 所以就是二分等比序列求和上场的时候了. 跟HDU 1588 Gauss Fibonacci的算法一样. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * B

HDU 2254 奥运(矩阵)

题目地址:HDU 2254 必须得吐槽一下..这题的数据是又弱又坑..样例不过都能AC..还有..居然还有重边..WA了一晚上.. 吐槽完毕,言归正传.. 根据离散数学里面的可达矩阵的性质,我们知道一个有向图的邻接矩阵的前n次幂的和即为可达矩阵,那么要求[t1-t2]之内的路径的条数,因为题目说了t1 = 0的时候为0.那么假设邻接矩阵为A,那么要求的就是A^(t1-1)+A^(t1)+...+A^(t2-1),为什么是从t1-1开始呢,因为邻接矩阵本身代表走一步的结果. 然后再加上离散化就可以

HDU - 2254 奥运 (求等比数列和)

Description 北京迎来了第一个奥运会,我们的欢呼声响彻中国大地,所以今年的奥运金牌 day day up! 比尔盖兹坐上鸟巢里,手里摇着小纸扇,看的不亦乐乎,被俺们健儿的顽强拼搏的精神深深的感动了.反正我的钱也多的没地方放了,他对自己说,我自己也来举办一个奥运会.看谁的更火.只是他的奥运会非常特别: 1 參加人员必须是中国人: 2 至少会加法运算(由于要计算本人获得的金牌数) 他知道中国有非常多的名胜古迹,他知道自己在t1 到 t2天内不可能把全部的地方都玩遍,所以他决定指定两个地方v

HDU 2254 奥运(数论+矩阵)

题目中文的不解释啊. .. 须要注意的就是:离散数学中,有向图的邻接矩阵A表示全部点之间路径长度为1的路径数量,A^n则表示路径长度为n的路径数量.故须要求某两点在(A^t1)~(A^t2)的路径数量之和. 奥运 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2251    Accepted Submission(s): 572 Pr

【矩阵快速幂】之奥运 hdu 2254

1.城市的编号不是从0到n-1,而是随便的一个数字,需要离散化否则不能存相关信息 2.城市数不超过30,也就是说我的方法开矩阵不超过60,但是我残念的一开始以为最多可能有20000个不同城市    血崩! 3.图中可能有重边,所以别用=1,要用++操作 4.询问中v1,v2可能在前面的城市编号集中没有出现,那么此时答案为0 5.t1可能比t2大,这种情况你就交换下t1,t2 好了接下来讲下解法: 由离散知识我们知道: ,矩阵A的n次方里面的(A^n)[i][j]表示从i到j且路径长度为n的不同路

HDU 2254

http://acm.hdu.edu.cn/showproblem.php?pid=2254 矩阵乘法两个经典问题的综合题,还要离散化和处理边界,好题啊好题 题意容易理解错,每一天是独立的,所以根据加法原理方案数是G^1+G^2+...+G^t /* 此题要求 (G^1+G^2+...+G^t2)-(G^1+G^2+...+G^(t1-1)) 求和的方法是再次二分,k=6时 G + G^2 + G^3 + G^4 + G^5 + G^6 = G + G^2 + G^3 + G^3 * (G +

hdu 2254(矩阵快速幂+分治)

题解:首先要城市要离散化,根据离散数学中可达矩阵的定义,给出一个有向图的邻接矩阵A,res = (A + E)^n表示这个矩阵n步后的可达情况,res[i][j]表示点i经过n步后到点j的方法数,那么给出了t1至t2后从v1到v2的方法数,就是要计算A^t1 + A^(t1 + 1) + - + A^(t2) 用了分治的思想计算,之前有写过模板http://blog.csdn.net/hyczms/article/details/46137531 #include <stdio.h> #inc

HDU 专题分类

[背包问题] 2602 Bone Collector 1114 Piggy-Bank 1203 I NEED A OFFER! 1171 Big Event in HDU 1059 Dividing 2844 Coins 2191 悼念512汶川大地震遇难同胞--珍惜现在,感恩生活 2159 FATE 1561 The more, The Better 1011 Starship Troopers 2639 Bone Collector II 3033 I love sneakers! 2955

HDU 1426 Sudoku Killer【DFS 数独】

自从2006年3月10日至11日的首届数独世界锦标赛以后,数独这项游戏越来越受到人们的喜爱和重视. 据说,在2008北京奥运会上,会将数独列为一个单独的项目进行比赛,冠军将有可能获得的一份巨大的奖品———HDU免费七日游外加lcy亲笔签名以及同hdu acm team合影留念的机会. 所以全球人民前仆后继,为了奖品日夜训练茶饭不思.当然也包括初学者linle,不过他太笨了又没有多少耐性,只能做做最最基本的数独题,不过他还是想得到那些奖品,你能帮帮他吗?你只要把答案告诉他就可以,不用教他是怎么做的