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

HDU 2254 - 奥运

时间:2016-07-06 23:14:51      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:

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

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

  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 }

 

HDU 2254 - 奥运

标签:

原文地址:http://www.cnblogs.com/nicetomeetu/p/5648307.html

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