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",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\n",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一样,怎么都是各种修改。
没想法,估计较难。
【推荐】FFA 2024大会视频回放:Apache Flink 的过去、现在及未来
【推荐】中国电信天翼云云端翼购节,2核2G云服务器一口价38元/年
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [杂谈]如何选择:Session 还是 JWT?
· 硬盘空间消失之谜:Linux 服务器存储排查与优化全过程
· JavaScript是按顺序执行的吗?聊聊JavaScript中的变量提升
· [杂谈]后台日志该怎么打印
· Pascal 架构 GPU 在 vllm下的模型推理优化
· 面试官:DNS解析都整不明白,敢说你懂网络?我:嘤嘤嘤!
· 2000 Star,是时候为我的开源项目更新下功能了
· [WPF UI] 为 AvalonDock 制作一套 Fluent UI 主题
· 不错的AI项目集合
· 基于.NET WinForm开发的一款硬件及协议通讯工具