zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    111         }
    112     }
    113 }
    我自倾杯,君且随意
  • 相关阅读:
    递归——8月4日
    练习:结构体、枚举类型——8月3日
    结构体、枚举类型——8月3日
    数组——7月25日
    类的复习——7月25日
    异常保护——7月25日
    类以及练习——7月25日
    javase学习小结二
    javase学习小结一
    产生随机数的方法
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/5648307.html
Copyright © 2011-2022 走看看