脑补了一下今天的比赛难度和之前zju-lzw出的题目画风迥异。

难度完全不是一个水平的好伐。

Probem A palindrome

给出一个$n$个元素的数组,可以任意指定一个数字$m$让所有$a_i = a_i \% m$。

使得最终得出的数组成为形如$\{1,2,3,2,1\}$的回文数组,求最大的$m$。

对于100%的数据$1\leq n \leq 10^5,1 \leq a_i \leq 10^9$

Sol: 我们要求同余方程 $ \left\{\begin{matrix} a_1 \equiv a_n (mod \ m)\\ ...\\  a_i \equiv a_{n-i+1}(mod \ m)\\  ...\\ a_n \equiv  a_1(mod \ m)\\ \end{matrix}\right.$的最大解$m$,

显然的我们考虑一种普遍的情况$a \equiv  b (mod \ p)$。

定理:上述结论成立的充分必要条件是$|a-b| \equiv 0 (mod \ p)$

充分性:设$a \leq b$ 那么有 $b-a = kp$即$b = kp + a$显然$a \equiv  b (mod \ p) $

必要性:证明同理。 所以这两个命题是等价的关系。

所以我们只要做差求gcd 就可以了。

  1. # include <bits/stdc++.h>
  2. using namespace std;
  3. const int N=1e5+;
  4. int a[N];
  5. int gcd(int a,int b)
  6. {
  7. if (b==) return a;
  8. return gcd(b,a%b);
  9. }
  10. int main()
  11. {
  12. int n; scanf("%d",&n);
  13. for (int i=;i<=n;i++) scanf("%d",&a[i]);
  14. int ans=;
  15. for (int i=;i<=n/;i++) ans=gcd(ans,abs(a[n-i+]-a[i]));
  16. if (ans==) puts("-1");
  17. else printf("%d\n",ans);
  18. return ;
  19. }

palindrome.cpp

Probem B factorial

给出一个序列$\{a_i\}$,完成三种操作:

1.区间 [l,r] 所有数+1

2.询问区间 [l,r] $\sum\limits_{i=l}^{r} a_i ! \ mod 10^9$

3.单点更新pos,val

对于100%的数据$n,m \leq 10^5 \ val,a_i\leq 10^9$

Sol: 都9102年了还是有人不知道线段树的骚操作。

模数是个合数你有什么好说的,一定有鬼。

发现$40! \ mod 10^9 = 0$于是我们所有的操作都打上了 $40$次的限制。

不需要懒标记,直接下放到叶子节点就可以。

复杂度$O(40\times n log_2 n)$

  1. # include <bits/stdc++.h>
  2. # define int long long
  3. using namespace std;
  4. const int N=1e5+;
  5. const int mo=1e9;
  6. int t[N<<],s[],g[N<<],a[N];
  7. int n,m;
  8. void build(int x,int l,int r)
  9. {
  10. if (l==r) { g[x]=a[l]; g[x]=min(g[x],41ll); t[x]=s[g[x]]; return;}
  11. int mid=(l+r)/;
  12. build(*x,l,mid);
  13. build(*x+,mid+,r);
  14. t[x]=(t[*x]+t[*x+])%mo;
  15. g[x]=g[*x]+g[*x+];
  16. }
  17. void update1(int x,int l,int r,int ql,int qr)
  18. {
  19. if (g[x]>=(r-l+)*) return;
  20. if (l==r) { g[x]++; g[x]=min(g[x],41ll); t[x]=s[g[x]]; return;}
  21. int mid=(l+r)/;
  22. if (ql<=mid) update1(*x,l,mid,ql,qr);
  23. if (qr>mid) update1(*x+,mid+,r,ql,qr);
  24. t[x]=(t[*x]+t[*x+])%mo;
  25. g[x]=g[*x]+g[*x+];
  26. }
  27. void update2(int x,int l,int r,int pos,int val)
  28. {
  29. if (l==r) { g[x]=val; g[x]=min(g[x],41ll); t[x]=s[g[x]]; return;}
  30. int mid=(l+r)/;
  31. if (pos<=mid) update2(*x,l,mid,pos,val);
  32. else update2(*x+,mid+,r,pos,val);
  33. t[x]=(t[*x]+t[*x+])%mo;
  34. g[x]=g[*x]+g[*x+];
  35. }
  36. int query(int x,int l,int r,int ql,int qr)
  37. {
  38. if (ql<=l&&r<=qr) return t[x];
  39. int mid=(l+r)/,ret=;
  40. if (ql<=mid) ret=(ret+query(*x,l,mid,ql,qr))%mo;
  41. if (qr>mid) ret=(ret+query(*x+,mid+,r,ql,qr))%mo;
  42. return ret;
  43. }
  44. signed main()
  45. {
  46. scanf("%lld%lld",&n,&m);
  47. for (int i=;i<=n;i++) {
  48. scanf("%lld",&a[i]);
  49. }
  50. s[]=; for (int i=;i<=;i++) s[i]=s[i-]*i%mo; s[]=;
  51. build(,,n);
  52. while (m--) {
  53. int op,l,r;
  54. scanf("%lld%lld%lld",&op,&l,&r);
  55. if (op==) {
  56. update1(,,n,l,r);
  57. } else if (op==) {
  58. printf("%lld\n",query(,,n,l,r));
  59. } else if (op==) {
  60. update2(,,n,l,r);
  61. }
  62. }
  63. return ;
  64. }

factorial.cpp

Problem C triangle

定义函数$f(x)  = $为一条直角边为$x$的正整数边长直角三角形种类数。

给出$q$组询问,每个询问含有一个值$n$ ,询问$f(x) = n$的最小整数解$x_{min}$

对于100%的数据,$q\leq 10^5 , 1\leq n \leq 10^6$

Sol : $n^2 +b^2 = c^2 $得出$n^2=(c+b)(c-b)-st(s=c+b,t=c-b)$

解得$c = \frac{s+t}{2} , b = \frac{s-t}{2} , t < s$。

结合三角形是边长是整数,即$b,c \in Z$

所以任意解$(s,t)$可以用$st = n^2,s > t, s \equiv t (mod \ 2)$

所以我们估计$f(n) = \frac{d(n^2)}{2}$规模的 , 手玩一下我们会发现。

对$n$质因数分解$n = 2^{k_2} \times 3 ^{k_3} \times 5^{k_5} ... $

所以$n^2 =  2^{2k_2} \times 3 ^{2k_3} \times 5^{2k_5} ...$

由于$s,t$的奇偶性必须同奇同偶,所以$2k_2$个$2$不能全分给$s,t$减少了一些方案。

其质因子需要任意分。三角形边长不能为0,所以排除$s=t$的情况,还需-1。

所以$f(n) = \frac{2{k_2}(2{k_3}+1)(2{k_5}+1)...}{2}$

令$f(x) = n$,对于选中的$x$,需要最小,使得$2{k_2}(2{k_3}+1)(2{k_5}+1)... = 2n+1$

用若干(取个14个就够了)个小素数来组成$m$可以保证m最小,依次考虑每次质数,背包一下就行了。

复杂度$O(qk^2) , k  =14$

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define N 2000010
  4. typedef long long LL;
  5. LL F[N];
  6. LL temp[N];
  7. const LL lim = 1e16;
  8. int p[] = {, , , , , , , , , , , , , , };
  9. void up(LL &x, LL y) { if (x == ) x = y; else x = min(x, y);}
  10.  
  11. int main()
  12. {
  13. F[] = ;
  14. for (int i = ; i <= p[]; ++i) {
  15. memset(temp, , sizeof(temp));
  16. for (int j = ; j < N; ++j) {
  17. if (F[j] == ) continue;
  18. int kk = ; LL s = ;
  19. while (true) {
  20. if (j*(kk*+) >= N) break;
  21. if (F[j] > lim / s) break;
  22. if (i > || kk == ) up(temp[j*(kk*+)], F[j]*s);
  23. ++kk;
  24. if (s > lim / p[i]) break;
  25. s = s * p[i];
  26. }
  27. }
  28. memcpy(F, temp, sizeof(temp));
  29. }
  30. int T, n; scanf("%d", &T);
  31. while (T--) {
  32. scanf("%d", &n);
  33. LL ans = lim + ;
  34. if (F[*n+]) ans = min(ans, F[*n+]);
  35. LL w = ;
  36. for (int k = ; k < ; ++k, w = w * ) {
  37. if ((*n+) % (*k-)) continue;
  38. LL t = F[(*n+)/(*k-)];
  39. if (t && t <= lim / w) ans = min(ans, t*w);
  40. }
  41. if (ans == lim+) ans = -;
  42. printf("%lld\n", ans);
  43. }
  44. return ;
  45. }

triangle.cpp

HGOI 20190519 题解的更多相关文章

  1. HGOI 20181028 题解

    HGOI 20181028(复赛备考) /* 真是暴力的一天,最后一题MLE?由于数组开得太大了!!! 270滚粗 考场上好像智商高了很多?!(假的) */ sol:暴力求解,然后没有数据范围吐槽一下 ...

  2. HGOI 20190310 题解

    /* 又是又双叒叕WA的一天... 我太弱鸡了... 今天上午打了4道CF */ Problem 1 meaning 给出q组询问,求下列函数的值$ f(a) = \max\limits_{0 < ...

  3. HGOI 20190303 题解

    /* 记一串数字真难. 5435 今天比赛又是hjcAK的一天. 今天开题顺序是312,在搞T1之前搞了T3 昨天某谷月赛真是毒瘤. 但是讲评的同学不错,起码T4看懂了... 构造最优状态然后DP的思 ...

  4. HGOI 20180224 题解

    /* The Most Important Things: ljc chat with fyh on QQTa说期末考Ta数学74分感觉不好但是我觉得fyh是地表最强的鸭~~(of course en ...

  5. HGOI 20190218 题解

    /* 又是AK局... hjc又双叒叕AK了... Hmmm...我侥幸 */ Problem A card 给出无序序列a[]可以选择一个数插入到合适的位置作为一次操作,至少多少次操作后可以把序列变 ...

  6. HGOI 20190217 题解

    /* for me,开训第一天 /beacuse 文化课太差被抓去补文化课了... 看一眼题 : AK局? 但是,Wa on test #10 in problem C 290! (就差那么一咪咪) ...

  7. HGOI 20181103 题解

    problem:把一个可重集分成两个互异的不为空集合,两个集合里面的数相乘的gcd为1(将集合中所有元素的质因数没有交集) solution:显然本题并不是那么容易啊!考场上想了好久.. 其实转化为上 ...

  8. HGOI 20181101题解

    /* 又是爆0的一天(不知道今年高考难不难,反正今天(信息学)真的难!) */ solution:对于两个数相加,有一个显然的结论就是要么不进位(相对于位数大的),要么(进最多一位) 然后对于整个数组 ...

  9. hgoi#20190519

    更好的阅读体验 来我的博客观看 T1-求余问题 Abu Tahun很喜欢回文. 一个数组若是回文的,那么它从前往后读和从后往前读都是一样的,比如数组{1},{1,1,1},{1,2,1},{1,3,2 ...

随机推荐

  1. celery 调用scrapy

    我的环境: celery 3.1.25 python 3.6.9 window10 celery tasks 代码如下,其中 QuotesSpider 是我的scrapy项目爬虫类名称 from ce ...

  2. 用python操作mysql数据库

    数据库的安装和连接 PyMySQL的安装 pip install PyMySQL python连接数据库 import pymysql db = pymysql.connect("数据库ip ...

  3. Collection接口的子接口——List接口

    https://docs.oracle.com/javase/8/docs/api/java/util/List.html public interface List<E> extends ...

  4. tasks.json 配置 解决vscode控制台乱码问题

    { "version": "2.0.0", "command": "dotnet", "tasks" ...

  5. O021、创建 Image

    参考https://www.cnblogs.com/CloudMan6/p/5393376.html   本节演示如何通过 Web GUI 和 CLI 两种方法创建image.   OpenStack ...

  6. hiper、sitespeed性能工具

    https://github.com/pod4g/hiper   hiper:   A statistical analysis tool for performance testing https: ...

  7. 好用的 python 工具集合

    图标处理小程序, 妈妈再也不用担心我不会制作图标了 # PythonMargick包可以到Unofficial Windows Binaries for Python Extension Packag ...

  8. 什么是DDoS攻击?

    本文转载自知道创宇云安全的知乎回答:DDoS 的肉鸡都是哪来的? 说到DDoS攻击,我们就不得不说“肉鸡”. “肉鸡”可谓是DDoS攻击的核心大杀器,作为一个要发起DDoS攻击的黑客来说,没有肉鸡就是 ...

  9. mysql统计表中条目个数的方法举例

    说明:以下标红且加大括号的均需要替换为实际待查询的表名或数据库名. [1].统计某张或某几张表的数据量: select count(*) from {TABLE_NAME}; #or select c ...

  10. SDRAM介绍

    一.             介绍 存储器的最初结构为线性,它在任何时刻,地址线中都只能有一位有效.设容量为N×M的存储器有S0-Sn-1条地址线:当容量增大时,地址选择线的条数也要线性增多,利用地址 ...