zoukankan      html  css  js  c++  java
  • 【HAOI2008】硬币购物

    既然没人写扩欧,那我就来一发吧。

    扩欧也还好,就是跑的有点慢,然后写的时候还有点烦,不过还是卡过去了。

    考场上看到这道题又蒙了。。。
    怎么回事第一题又要爆零了?

    然后我打了个暴力测了一下极限数据根本过不去(幸好没把电脑整死机)

    于是想了又想,整出了个 $ O(s* t)$的扩欧算法(打了一个小时的样子)。

    (话说正解好像容斥)

    原本搞了下循环展开结果好像会更慢。。。


    讲一下思路:用扩欧解。

    安利扩欧博客:Judge's Class


      预处理解之前我们要先用扩欧求出:
      c1*x + c2*y = gcd(c1,c2) 中的 x和y (以及gcd),记录下来,
      然后 c1、c2 除以 gcd(c1,c2)。(会扩欧的话就能懂吧。)
      然后我们先 O(s log s) 预处理用 c1、c2 能拼出 s 的解。
      (即 c1*x1 + c2*y1 = s 中 x1和y1 的解)
      然后我们令 x1 达到最小正整数状态,即 y1 达到最大解。
      这时如果 y1 为负数,则无解,将数组中的值设为-1,break。
      否则我们用数组记录下此时的解。

      那么 c3、c4 也是同理这样处理。

      这样处理完之后我们发现如果没有 d 数组的限制,y/c2 就是方案数,
      那么我们考虑一下 d1对x1 的限制 以及 d2 对 y1 的限制求出解的方案数。
      然后记录答案在 f 数组里面,至于 c3、c4 就记录进 g 数组。
      然后 O(s) 滚出答案。

     1 //by Judge
     2 #include<bits/stdc++.h>
     3 #define rint register int
     4 #define ll long long
     5 using namespace std;
     6 const int M=1e5+5;
     7 #idndef Judge
     8 #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     9 #endif
    10 char buf[1<<21],*p1,*p2;
    11 inline int read(){ int x=0,f=1; char c=getchar();
    12     for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    13     for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
    14 } int c1,c2,c3,c4,d1,d2,x11,x22,y11,y22,d[5];
    15 int X1[M],X2[M],Y1[M],Y2[M],f[M],g[M];
    16 int ex_gcd(int a,int b,int& x,int& y){ /* 套个板子,忘了就现推 */
    17     if(!b) return x=1,y=0,a;
    18     int d=ex_gcd(b,a%b,y,x);
    19     return y-=a/b*x,d;
    20 }
    21 int main(){
    22     c1=read(),c2=read();
    23     c3=read(),c4=read();
    24     d1=ex_gcd(c1,c2,x11,y11);
    25     d2=ex_gcd(c3,c4,x22,y22);
    26     c1/=d1,c2/=d1,c3/=d2,c4/=d2;
    27     /*  预处理出解  */
    28     for(rint s=1;s<=1e5;++s){
    29         rint tmp=s,x=x11,y=y11;
    30         rint a=c1,b=c2;
    31         if(tmp%d1){
    32             X1[s]=Y1[s]=-1;
    33             continue;
    34         }
    35         tmp/=d1,x*=tmp,y*=tmp;
    36         
    37         y+=x/b*a,x%=b;
    38         if(x<0) x+=b,y-=a;
    39         if(y>=0) X1[s]=x,Y1[s]=y;
    40         else X1[s]=Y1[s]=-1;
    41     }
    42     for(rint s=1;s<=1e5;++s){
    43         rint tmp=s,x=x22,y=y22;
    44         rint a=c3,b=c4;
    45         if(tmp%d2){
    46             X2[s]=Y2[s]=-1;
    47             continue;
    48         }
    49         tmp/=d2,x*=tmp,y*=tmp;
    50         
    51         y+=x/b*a,x%=b;
    52         if(x<0) x+=b,y-=a;
    53         if(y>=0) X2[s]=x,Y2[s]=y;
    54         else X2[s]=Y2[s]=-1;
    55     }
    56     for(rint T=read(),S;T;--T){
    57         ll ans=0;
    58         for(int i=1;i<=4;++i)
    59             d[i]=read();
    60         S=read(),f[0]=g[0]=1;
    61         /*  考虑限制求出方案数  */
    62         for(rint s=1;s<=S;++s){
    63             rint tmp=s,a=c1,b=c2;
    64             rint x=X1[s],y=Y1[s];
    65             if(x<0||y<0){
    66                 f[s]=0;
    67                 continue;
    68             }
    69             rint maxX=min(x+y/a*b,d[1]);
    70             
    71             if(d[2]<y) x+=(y-d[2]+a-1)/a*b;
    72             if(x>maxX){
    73                 f[s]=0;
    74                 continue;
    75             }
    76             f[s]=(maxX-x)/b+1;
    77         }
    78         for(rint s=1;s<=S;++s){
    79             rint tmp=s,a=c3,b=c4;
    80             rint x=X2[s],y=Y2[s];
    81             if(x<0||y<0){
    82                 g[s]=0;
    83                 continue;
    84             }
    85             rint maxX=min(x+y/a*b,d[3]);
    86             
    87             if(d[4]<y) x+=(y-d[4]+a-1)/a*b;
    88             if(x>maxX){
    89                 g[s]=0;
    90                 continue;
    91             }
    92             g[s]=(maxX-x)/b+1;
    93         }
    94         /*  O(s) 滚出答案  */
    95         for(rint i=0;i<=S;++i)
    96             ans+=1ll*f[i]*g[S-i];
    97         printf("%lld
    ",ans);
    98     } return 0;
    99 }
  • 相关阅读:
    python模块--time模块
    python模块--如何相互调用自己写的模块
    Animating Views Using Scenes and Transitions
    fragment 切换
    android textview 设置text 字体
    android intent 5.1
    android EditView ime
    animation of android (4)
    animation of android (3)
    animation of android (2)
  • 原文地址:https://www.cnblogs.com/Judge/p/9887371.html
Copyright © 2011-2022 走看看