zoukankan      html  css  js  c++  java
  • 2019银联高校极客挑战赛 复赛

    一直不在状态……

    想着各种事情……

    A.

    正常的方法是预处理k!和inv(k!),然后每次询问O(1)。

    然后某同学的方法是dp,O(n*m)也能过。

    f(i,j,0)和f(i,j,1)吗?i<=n,j<=m,0和1分别代表是否已经选择F吗。

    B.

    对于a,是x的倍数,且不是y的倍数(其中p%x==0,y%x==0,p%y==0)

    x乘上某个数,这个数除以z(z为不可以使用的约数的乘积,详见代码)为r(计算0~z-1)。

    则对于b,是(p/x)的倍数

    不好写。。。

    时间复杂度:

    预处理:k个质因数(<=6),2^k * 对应的大小(<=p)

    约数的个数*(k+k)

    还有更快的方法

    题解:数论方式分析。

    a=px+y

    y*b=p的倍数

    则b是p/y的倍数。

    然后枚举y。

    写得很快。。。

    看群里还有使用mobius的,比赛时想过,但没想到。

    对于数字a,b

    gcd(a,p)=d

    然后b为p/d的倍数即可。

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cmath>
      4 #include <cstring>
      5 #include <string>
      6 #include <algorithm>
      7 #include <iostream>
      8 using namespace std;
      9 #define ll long long
     10 
     11 const double eps=1e-8;
     12 const ll inf=1e9;
     13 const ll mod=1e9+7;
     14 const int maxn=1e5+10;
     15 
     16 ///2,3,5,7,11,13
     17 
     18 struct node
     19 {
     20     ll g;
     21     ///large to small
     22     ll a[10],b[10];
     23 }f[maxn];
     24 
     25 ll zhi[maxn],zhi_cnt,maxv=1e5;
     26 ll x[300],gx[300],y[130][maxn];
     27 bool vis[maxn],use[maxn];
     28 ll p;
     29 
     30 ///10^5*64
     31 void dfs(ll i,ll j,ll k)
     32 {
     33     if (k==f[p].g+1)
     34     {
     35         ll l,z;
     36         y[j][0]=0;
     37         x[j]=i;
     38         z=f[p].g;
     39         for (l=1;l<=i;l++)
     40         {
     41             for (k=1;k<=z;k++)
     42                 if (l%zhi[f[p].a[k]]==0 && use[k])
     43                     break;
     44             if (k==z+1)
     45                 y[j][l]=y[j][l-1]+1;
     46             else
     47                 y[j][l]=y[j][l-1];
     48         }
     49         gx[j]=y[j][i];
     50         return;
     51     }
     52     use[k]=0;
     53     dfs(i,j*2,k+1);
     54     use[k]=1;
     55     dfs(i*zhi[f[p].a[k]],j*2+1,k+1);
     56 }
     57 
     58 ll work(ll u,ll v)
     59 {
     60     ll r=0,i,j;
     61     v/=u;
     62 
     63     i=1,j=1;
     64     while (i<=f[u].g && j<=f[p].g)
     65     {
     66         if (f[u].a[i]==f[p].a[j])
     67         {
     68             if (f[u].b[i]==f[p].b[j])
     69                 r=r*2;
     70             else
     71                 r=r*2+1;
     72             i++;
     73             j++;
     74         }
     75         else if (f[u].a[i]>f[p].a[j])
     76             i++;
     77         else
     78         {
     79             j++;
     80             r=r*2+1;
     81         }
     82     }
     83     while (j<=f[p].g)
     84         r=r*2+1,j++;
     85 
     86     return v/x[r]*gx[r]+y[r][v%x[r]];
     87 }
     88 
     89 int main()
     90 {
     91     ll t,i,j,k,maxv=1e5;
     92     ll n,m,sum;
     93     for (i=2;i<=maxv;i++)
     94     {
     95         if (!vis[i])
     96         {
     97             zhi[++zhi_cnt]=i;
     98             f[i].g=1;
     99             f[i].a[1]=zhi_cnt;
    100             f[i].b[1]=1;
    101         }
    102         for (j=1;j<=zhi_cnt;j++)
    103         {
    104             k=i*zhi[j];
    105             if (k>maxv)
    106                 break;
    107             vis[k]=1;
    108             f[k]=f[i];
    109             if (f[i].a[f[i].g]==j)
    110                 f[k].b[f[k].g]++;
    111             else
    112             {
    113                 f[k].g++;
    114                 f[k].a[f[k].g]=j;
    115                 f[k].b[f[k].g]=1;
    116             }
    117             if (i%zhi[j]==0)
    118                 break;
    119         }
    120     }
    121 
    122     scanf("%lld",&t);
    123     while (t--)
    124     {
    125         scanf("%lld%lld%lld",&n,&m,&p);
    126 //        if (p==1)
    127 //        {
    128 //            printf("%lld
    ",n*m);
    129 //            continue;
    130 //        }
    131         dfs(1,0,1);
    132 
    133         sum=0;
    134         for (i=1;i<=p;i++)
    135             if (p%i==0)
    136             {
    137                 j=p/i;
    138 
    139                 sum+=work(i,n)*(m/j);
    140             }
    141         printf("%lld
    ",sum);
    142     }
    143     return 0;
    144 }
    145 /*
    146 5
    147 1000000000 1000000000 1
    148 1000000000 1000000000 2
    149 1000000000 1000000000 10
    150 100000000 100000000 2
    151 10 20 15
    152 1000000000 1000000000 30030
    153 100000000 100000000 30030
    154 
    155 1
    156 9 9 9
    157 1
    158 6 6 12
    159 
    160 1
    161 20 20 11
    162 
    163 1
    164 10 10 6
    165 */

    场上感觉,然后看了题解,以下想法基本是错的……

    C.

    a1,b1,c1

    a2,b2,c2

    要求

    a1<b2<c1

    a2<b1<c2

    有可能要按照某种方式排序

    两组条件,两者互相约束。

    然后就不会做了……

    题解:

    取反求,变成i能赢j的条件,此时的条件可求。

    然后就是偏序的子问题。

    不同数组元素的比较,其实还是比较,二维偏序。

    cj<bi bj<ai

    改为

    c,b;b,a数组 为 同一个数组(表示的符号相同)表示即可。

    D.

    一开始以为是图,觉得不可做,

    后面发现是树。。。

    点分治

    结合题解想了一想,也许可以???

    也许可以分为内部处理的 和 通过子根相连的

    处理^k(k<=13)

    各种多项式操作。 (题解:二项式定理)

    看群里说对于k较小的情况,有更好的做法,cf的某些题???

    题解:树形DP。

    树本身的结构已经提供了层次感???

    lca为当前根。

    未证实正确的想法:

    E.

    末尾有0的操作。

    只可能为

    a->b->c->b->c

    b->c->b->c

    处理每个区间的最小/最大值

    每次a->b时进行修改,

    提前记录,也许要额外建一棵树,

    数目不多。

    题解的方法,特别是最后一部分没看懂。。。

    F.

    跟E一样,怎么都是各种修改。

    没想法,估计较难。

  • 相关阅读:
    C语言程序设计第5堂作业
    C语言程序设计第4堂作业
    gets和fgets函数的区别
    编写一个程序实现strcpy函数的功能
    编写一个程序实现strcmp函数的功能
    编写一个程序实现strcat函数的功能
    11-1. 通讯录的录入与显示(10)
    11-0. 平面向量加法(10)
    10-4. 字符串循环左移(20)
    10-3. 字符串逆序(15)
  • 原文地址:https://www.cnblogs.com/cmyg/p/11333010.html
Copyright © 2011-2022 走看看