T1

题目大意, \(S_{i,j}=\sum_{k=i}^j a_k\) ,求 \(ans=\min\{ S_{i,j}\mod P|S_{i,j}\mod P\ge K \}\)

其中 \(i\le j\),\(\{ S_{i,j}\mod P|S_{i,j}\mod P\ge K \}\) 非空

设 \(s_i\) 是取模的前缀和,显然是要满足条件的 \((s_j-s_i)\mod P\) 最小

对于一个 \(s_j\) ,要 \(s_i\) 最大,变成一个查询前驱的问题

但是有限制,考虑分类讨论

  1. \(s_j\ge s_i\) 时原式变为 \(s_j-s_i\) ,要满足要求, \(s_i\) 最大是 \(s_j-K\),直接查询 \(s_j-K\) 的前驱

    原因:\(s_j-(s_j-K)=K\ge K\)

  2. \(s_j<s_i\) 时原式变为 \(s_j-s_i+P\) ,要满足要求, \(s_i\) 最大是 \(s_j-K+P\),查询 \(s_j-K+P\) 的前驱

查询完,将 \(s_i\) 插入

至于查询前驱,和普通的平衡树有一点区别:不严格前驱

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=100005,INF=100000000;
  4. int n,K,P,ans=INF,s[N];
  5. int cnt[N],val[N],sz[N],fa[N],ch[N][2],root,tot;
  6. inline int Get(int x) { return ch[fa[x]][1]==x; }
  7. inline void Up(int x) { sz[x]=cnt[x]+sz[ch[x][0]]+sz[ch[x][1]]; }
  8. inline void Rot(int x) {
  9. register int y=fa[x],z=fa[y],k=Get(x);
  10. ch[z][Get(y)]=x,fa[x]=z;
  11. ch[y][k]=ch[x][k^1],fa[ch[x][k^1]]=y;
  12. ch[x][k^1]=y,fa[y]=x;
  13. Up(y),Up(x);
  14. }
  15. inline void Splay(int x,int goal=0) {
  16. for(int y;(y=fa[x])^goal;Rot(x))
  17. if(fa[y]^goal)Rot(Get(x)^Get(y)?x:y);
  18. if(!goal)root=x;
  19. }
  20. inline void Find(int x) {
  21. if(!root)return;
  22. register int u=root;
  23. while(ch[u][x>val[u]] && x^val[u])
  24. u=ch[u][x>val[u]];
  25. Splay(u);
  26. }
  27. inline void Ins(int x) {
  28. register int u=root,fu=0;
  29. while(u && val[u]^x)fu=u,u=ch[u][x>val[u]];
  30. if(u)cnt[u]++;
  31. else {
  32. u=++tot;
  33. if(fu)ch[fu][x>val[fu]]=u;
  34. ch[u][0]=ch[u][1]=0;
  35. fa[u]=fu,val[u]=x;
  36. cnt[u]=sz[u]=1;
  37. }
  38. Splay(u);
  39. }
  40. inline int Pre(int x) {
  41. register int u=root,mx=-INF;
  42. while(1) {
  43. if(!u)return mx;
  44. if(val[u]>x)u=ch[u][0];
  45. else mx=max(mx,val[u]),u=ch[u][1];
  46. }
  47. }
  48. int main() {
  49. scanf("%d%d%d",&n,&K,&P);
  50. Ins(0);
  51. for(int i=1;i<=n;i++)
  52. scanf("%d",s+i),
  53. (s[i]+=s[i-1])%=P;
  54. for(int i=1,xx,yy;i<=n;i++) {
  55. xx=Pre(s[i]-K);
  56. yy=Pre(s[i]-K+P);
  57. // printf("%d %d\n",xx,yy);
  58. ans=min(ans,min(s[i]-xx,s[i]-yy+P));
  59. Ins(s[i]);
  60. }
  61. printf("%d",ans);
  62. }

T2

\(n\) 个 \(D\) 维的点,两点 \(A(x_1,x_2,\cdots,x_D),B(X_1,X_2,\cdots,X_D)\) 曼哈顿距离是 \(\sum_{i=1}^D |x_i-X_i|\)

问两点间的最大距离

60

由于 \(D=2\) ,将点放入平面直角坐标系,求的是 \(\max\{ |x_i-x_j|+|y_i-y_j|\}\)

取绝对值,又四种情况

\(+x_i-x_j+y_i-y_j\)

\(+x_i-x_j-y_i+y_j\)

\(-x_i+x_j+y_i-y_j\)

\(-x_i+x_j-y_i+y_j\)

再合并一下

\((+x_i+y_i)+(-x_j-y_j)\)

\((+x_i-y_i)+(-x_j+y_j)\)

\((-x_i+y_i)+(+x_j-y_j)\)

\((-x_i-y_i)+(+x_j+y_j)\)

发现答案就在之中,

于是分类讨论两个括号,相加取 \(\max\) 即可

100

将上面算法改一下即可:将分类讨论变成 \(O(2^D)\) 的全排列

排列同一个点的符号,然后记录对于所有点每一种排列的最大、最小值

最后最大-最小取最大即可


还可以更快的优化:

因为 \(x_i-x_j=-x_i-(-x_j)\)

所以没有必要枚举第一个系数

直接定为 1

总复杂度 \(O(nD\times 2^{D-1})\)


  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=1000005,INF=100000000;
  4. int n,D,up,tot,x[6],mx[40],mn[40],ans;
  5. void dfs(int st,int v) {
  6. if(st>D) {
  7. tot++;
  8. mx[tot]=max(mx[tot],v);
  9. mn[tot]=min(mn[tot],v);
  10. return;
  11. }
  12. dfs(st+1,v+x[st]);
  13. dfs(st+1,v-x[st]);
  14. }
  15. int main() {
  16. scanf("%d%d",&n,&D);
  17. up=1<<D;
  18. for(int i=1;i<=up;i++)
  19. mx[i]=-INF,mn[i]=+INF;
  20. n=0;
  21. while(scanf("%d",&x[1])!=EOF) {
  22. for(int j=2;j<=D;j++)
  23. scanf("%d",&x[j]);
  24. tot=0,dfs(2,x[1]);
  25. }
  26. for(int i=1;i<=up;i++)
  27. ans=max(ans,mx[i]-mn[i]);
  28. printf("%d",ans);
  29. }

T3

求 \(\dfrac{1}{x}+\dfrac{1}{y}=\dfrac{1}{n}\) 的本质不同的解的个数

\[\begin{aligned}
\dfrac{1}{x}+\dfrac{1}{y} &= \dfrac{1}{n} \\
nx+ny &= xy \\
n^2 &= n^2-n(x+y)+xy \\
(x-n)(y-n) &= n^2
\end{aligned}
\]

所以,只要 \((x-n)\) 和 \((y-n)\) 是 \(n^2\) 的约数,就是一个解

于是分解质因数求 \(n^2\) 因数个数,注意

  1. 求的是 \(n^2\) 得因数个数,对于 \(n\) 得一个质因数次数要乘二
  2. 如果到最后 \(n>1\) 说明还有一个质因数,答案乘 3
  3. 要求本质不同的解,即 \(\lceil \dfrac{ans}{2} \rceil\)
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. LL n,ans=1,cnt;
  5. int main() {
  6. scanf("%lld",&n);
  7. for(LL i=2;i<=sqrt(n);i++) {
  8. if(n%i==0) {
  9. cnt=0;
  10. while(n%i==0)
  11. n/=i,++cnt;
  12. ans*=cnt<<1|1;
  13. }
  14. }
  15. if(n>1)ans*=3;
  16. printf("%lld",ans+1>>1);
  17. }

T4

题目大意: 对 \(n\times m\) 得地图染色,要求每一个 \(2\times 2\) 得小方阵内颜色不能相同

问方案数模 \(P\),\(n\le 10^{100},m\le 5\)

\(m\le 5\),显然的状压 dp

50

设 \(f_{i,s}\) 为前 \(i-1\) 行放满,第 \(i\) 行状态为 \(s\) 得方案

有 \(f_{i,s}=\sum f_{i-1,t}\) ,其中 \(s,t\) 为一组合法状态

复杂度 \(O(n\times 2^m\times 2^m)\) 期望 50

100

然后转移是固定的,设 \(g_{s,t}=1\),其中 \(s,t\) 为一组合法状态

将 \(f_i\) 变成一个 \(2^m\times2^m\) 的矩阵

可得 \(f_{i}=f{i-1}\times g\)

即 \(f(n)=f(1)\times g^{n-1}\)

\(f(1)\) 就第一行是 1,其余是 0

所以用矩阵快速幂,最后输出矩阵中所有元素和

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. int len,tn,m,P,up,p[20],sum,n[200],ck[40][40];
  5. char s[200];
  6. inline bool chk(int S,int T) {
  7. for(int i=0;i<m-1;i++) {
  8. if(!(S&p[i]) && !(S&p[i+1]) && !(T&p[i]) && !(T&p[i+1]))return 0;
  9. if((S&p[i]) && (S&p[i+1]) && (T&p[i]) && (T&p[i+1]))return 0;
  10. }
  11. return 1;
  12. }
  13. struct mat {
  14. int a[40][40];
  15. mat() { memset(a,0,sizeof(a)); }
  16. inline mat operator*(mat x) {
  17. register mat res;
  18. for(int i=0;i<=up;i++)
  19. for(int j=0;j<=up;j++)
  20. for(int k=0;k<=up;k++)
  21. (res.a[i][j]+=a[i][k]*x.a[k][j])%=P;
  22. return res;
  23. }
  24. }ans,tmp;
  25. int main() {
  26. for(int i=0;i<=10;i++)p[i]=1<<i;
  27. scanf("%s%d%lld",s+1,&m,&P);
  28. len=strlen(s+1),up=(1<<m)-1;
  29. for(int i=1;i<=len;i++)n[i]=s[len-i+1]^48;
  30. n[1]--;
  31. for(int i=1;i<=len;i++) {
  32. if(n[i])break;
  33. n[i]+=10,--n[i+1];
  34. }
  35. while(!n[len] && len)--len;
  36. for(int j=0;j<=up;j++)
  37. for(int k=0;k<=up;k++)
  38. tmp.a[j][k]=chk(j,k);
  39. for(int i=0;i<=up;i++)ans.a[1][i]=1;
  40. while(len) {
  41. if(n[1]&1)ans=ans*tmp;
  42. tmp=tmp*tmp;
  43. for(int i=len;i>1;i--)
  44. n[i-1]+=10*(n[i]&1),n[i]>>=1;
  45. n[1]>>=1;
  46. while(!n[len] && len)--len;
  47. }
  48. for(int i=0;i<=up;i++)
  49. for(int j=0;j<=up;j++)
  50. (sum+=ans.a[i][j])%=P;
  51. printf("%d",sum);
  52. }

总结

  1. 对于取模的分类讨论
  2. 对于绝对值的分类讨论
  3. 因式分解
  4. 转移固定就用矩阵乘

2021.05.04【NOIP提高B组】模拟 总结的更多相关文章

  1. 5820. 【NOIP提高A组模拟2018.8.16】 非法输入(模拟,字符串)

    5820. [NOIP提高A组模拟2018.8.16] 非法输入 (File IO): input:aplusb.in output:aplusb.out Time Limits: 1000 ms   ...

  2. JZOJ 5818. 【NOIP提高A组模拟2018.8.15】 做运动

    5818. [NOIP提高A组模拟2018.8.15] 做运动 (File IO): input:running.in output:running.out Time Limits: 2000 ms  ...

  3. JZOJ 5812. 【NOIP提高A组模拟2018.8.14】 区间

    5812. [NOIP提高A组模拟2018.8.14] 区间 (File IO): input:range.in output:range.out Time Limits: 1000 ms  Memo ...

  4. 2021.06.05【NOIP提高B组】模拟 总结

    T1 题意:给你一个 \(n\) 个点 \(n\) 条边的有向图, 求每个店经过 \(K\) 条边后的边权和.最小边权 \(K\le 10^{10}\) 考试时:一直想着环,结果一直不知道怎么做 正解 ...

  5. 2021.05.05【NOIP提高B组】模拟 总结

    T1 给你一棵树,要求增加最少的边权是的从根到每一个叶子的长度相等 不能改变原有的最大长度 这是一个贪心:尽可能往深度小的边增加 先预处理出 \(mx_i\) 表示从 \(i\) 到叶子的最大长度 然 ...

  6. [JZOJ5817] 【NOIP提高A组模拟2018.8.15】 抄代码

    Description J 君是机房的红太阳,每次模拟她总是 AK 虐场.然而在 NOIP2117 中,居然出现了另一位 AK 的选手 C 君! 这引起了组委会的怀疑,组委会认为 C 君有抄袭 J 君 ...

  7. [JZOJ5818] 【NOIP提高A组模拟2018.8.15】 做运动

    Description 一天,Y 君在测量体重的时候惊讶的发现,由于常年坐在电脑前认真学习,她的体重有了突 飞猛进的增长. 幸好 Y 君现在退役了,她有大量的时间来做运动,她决定每天从教学楼跑到食堂来 ...

  8. 【NOIP提高A组模拟2018.8.14】 区间

    区间加:差分数组修改 O(n)扫描,负数位置单调不减 #include<iostream> #include<cstring> #include<cstdio> # ...

  9. [jzoj 5782]【NOIP提高A组模拟2018.8.8】 城市猎人 (并查集按秩合并+复杂度分析)

    传送门 Description 有n个城市,标号为1到n,修建道路花费m天,第i天时,若gcd(a,b)=m-i+1,则标号为a的城市和标号为b的城市会建好一条直接相连的道路,有多次询问,每次询问某两 ...

  10. [jzoj 5781]【NOIP提高A组模拟2018.8.8】秘密通道 (最短路)

    传送门 Description 有一副nm的地图,有nm块地,每块是下列四种中的一种: 墙:用#表示,墙有4个面,分别是前面,后面,左面,右面. 起点:用C表示,为主角的起点,是一片空地. 终点:用F ...

随机推荐

  1. Could not autowire. No beans of 'JavaMailSenderImpl' type found

  2. spring报错can't find resources

    整合spring的时候报错can't find resource[../././.xml] 这两天在整个spring,发现单元测试的时候就可以正常运行,放在tomcat中就报错initial cont ...

  3. 编译python(cpython)的源码及其用途

    获取python的源码 3.x及最新版本的源码:https://github.com/python/cpython python2.7分支的源码:https://github.com/python/c ...

  4. c++对c的拓展_指针的引用

    套用引用公式:Type & ref =val; 假设:type 类型为int * 由公式得 int * & ref = val; // int * *const ref=&va ...

  5. LC-26

    class Solution { public int removeDuplicates(int[] nums) { int slowIndex = 0, fastIndex = 1; if (num ...

  6. Mybatis-Plus查询整理

    1.Hibernate是全ORM(对象关系映射)框架,利用完整的javabean对象与数据库映射结构来自动生成sql. 2.Mybatis是半ORM框,仅有字段映射,需要手写sql语句和对象字段结合生 ...

  7. 2021.08.09 P5018 对称二叉树(树形结构)

    2021.08.09 P5018 对称二叉树(树形结构) [P5018 NOIP2018 普及组] 对称二叉树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 求一棵子树,关 ...

  8. 读完学会shell语法,shell脚本80%已经学会

    第3章 shell语法讲解 3.1 shell运算讲解 3.1.1 运算符的讲解 3.1.2 shell运算方式的讲解 3.1.2.1 $(())运算 [root@m01 test_init] # a ...

  9. 简单手写一个jqurey

    1 /** 2 * @description 手写jquery 3 * @author ddxldxl 4 */ 5 class Jquery { 6 constructor(selector) { ...

  10. XCTF练习题---WEB---view_source

    XCTF练习题---WEB---view_source flag:cyberpeace{662b1cf989a0a7999a5589290ce5a88e} 解题步骤: 1.观察题目,打开场景 2.根据 ...