T1 入阵曲

好了,又一个考试败笔题。

也就是在那个时候,小 F 学会了矩阵乘法。让两个矩阵乘几次就能算出斐波那契数, 真是奇妙无比呢。

不过, 小 F 现在可不想手算矩阵乘法——他觉得好麻烦。取而代之的,是一个简单的小问题。

题目清奇的叙述i引起小马清奇的思路——矩阵快速幂优化dp。于是开始了推柿子。。。

一小时,两小时,可恶,还没推出来,唉出来了。。等等,不对。。。

两个半小时将近三小时的时候,算了打暴力吧。。

然后就,唉。

可是这题并非矩阵乘法,草。。。。

那他疯狂diss我干嘛~~

60分很好拿到,不过当时太慌就没打前缀和,n^6暴力直接跑了,惨淡45。。。

正解就是在60暴力上加了一个优化。

he[k]表示两行之间的矩形的前缀和,num[k]表示出现的矩形的对数(记录有几对)。

因为,在模k意义下的前缀和,任取两个矩形前缀和相减必定是k的倍数。

num也就是统计模k相同的矩阵的个数。

  1. 1 #include<bits/stdc++.h>
  2. 2 #define write(X) printf("%lld",X)
  3. 3 #define read(X) scanf("%lld",&X)
  4. 4 #define rint register long long
  5. 5 #define int long long
  6. 6 using namespace std;
  7. 7
  8. 8 const int NN=1e6+10;
  9. 9 int n,m,p,rp;
  10. 10 int num[NN],he[NN];
  11. 11 int sum[405][405],a[405][405];
  12. 12
  13. 13 inline void init(){
  14. 14 read(n); read(m); read(p);
  15. 15 for(rint i=1;i<=n;i++) for(rint j=1;j<=m;j++)
  16. 16 read(a[i][j]),a[i][j]%=p;
  17. 17 for(rint i=1;i<=n;i++) for(rint j=1;j<=m;j++)
  18. 18 sum[i][j]=(sum[i][j-1]+a[i][j])%p;
  19. 19 for(rint i=1;i<=n;i++) for(rint j=1;j<=m;j++)
  20. 20 sum[i][j]=(sum[i][j]+sum[i-1][j])%p;
  21. 21 }
  22. 22
  23. 23 namespace WSN{
  24. 24 inline int main(){
  25. 25 init();
  26. 26 for(rint i=0;i<n;i++)
  27. 27 for(rint j=i+1;j<=n;j++){
  28. 28 num[0]=1;
  29. 29 for(rint k=1;k<=m;k++){
  30. 30 he[k]=(sum[j][k]-sum[i][k]+p)%p;
  31. 31 rp+=num[he[k]]++;
  32. 32 }
  33. 33 for(int k=1;k<=m;k++) num[he[k]]=0;
  34. 34 }
  35. 35 write(rp); putchar('\n');
  36. 36 return 0;
  37. 37 }
  38. 38 }
  39. 39 signed main(){return WSN::main();}

T2 将军令

题目猛一看,这不就是小胖守皇宫吗?不过K的值更大就不会考虑了。。

其实,应该考虑贪心。

从深度最深的点开始向上找他的K级父亲,这样的话从K级父亲开始将能够管到的点全部标记,找就可以了。

  1. 1 #include<bits/stdc++.h>
  2. 2 #define r(X) scanf("%d",&X)
  3. 3 #define w(X) printf("%d\n",X)
  4. 4 #define Min(A,B) ((A)<(B)?(A):(B))
  5. 5 #define rint register int
  6. 6 using namespace std;
  7. 7
  8. 8 const int NN=1e5+10;
  9. 9 int n,k,t,d[NN],fa[NN][25],ans;
  10. 10 bool vis[NN];
  11. 11 struct SNOW{int to,next;}; SNOW e[NN<<1]; int head[NN],tot;
  12. 12 inline void add(int x,int y){ e[++tot]=(SNOW){y,head[x]}; head[x]=tot;}
  13. 13 struct snow{
  14. 14 int dep,id;
  15. 15 }; snow m[NN];
  16. 16 inline bool cmp(snow a,snow b){return a.dep>b.dep;}
  17. 17
  18. 18 inline void dfs1(int f,int x){
  19. 19 for(rint i=head[x];i;i=e[i].next){
  20. 20 int y=e[i].to;
  21. 21 if(y==f) continue;
  22. 22 m[y].dep=m[x].dep+1; fa[y][1]=x;
  23. 23 for(rint j=2;j<=Min(k,m[y].dep);j++) fa[y][j]=fa[fa[y][j-1]][1];
  24. 24 dfs1(x,y);
  25. 25 }
  26. 26 }
  27. 27
  28. 28 inline void dfs2(int pre,int x,int tmp){
  29. 29 vis[x]=1;
  30. 30 if(!tmp) return;
  31. 31 for(rint i=head[x];i;i=e[i].next){
  32. 32 int y=e[i].to;
  33. 33 if(y==pre) continue;
  34. 34 dfs2(x,y,tmp-1);
  35. 35 }
  36. 36 }
  37. 37
  38. 38 namespace WSN{
  39. 39 inline int main(){
  40. 40 r(n); r(k); r(t);
  41. 41 for(rint i=1,x,y;i<n;i++)
  42. 42 r(x),r(y),add(x,y),add(y,x),m[i].id=i;
  43. 43 if(k==0) {w(n);return 0;}
  44. 44 m[n].id=n;
  45. 45 dfs1(0,1);
  46. 46 sort(m+1,m+n+1,cmp);
  47. 47 for(rint i=1;i<=n;i++) if(!vis[m[i].id]){
  48. 48 rint f=fa[m[i].id][k];
  49. 49 ans++,dfs2(-1,f,k);
  50. 50 }
  51. 51 w(ans);
  52. 52 return 0;
  53. 53 }
  54. 54 }
  55. 55 signed main(){return WSN::main();}

T3 星空

此题思维量较大,融合状压,最短路,差分思想于一体。

记录1为灭,0为开。

首先可以看到操作是在一段上取反,可以用差分O(1)进行修改,于是我们先维护一个差分数组nu(注意n++,以为要把最后一个数的差分记上)。这样,这个0/1串差分数组上就有不超过2×k个1(因为原数组中每出现一个1,差分数组中要可能出现两个)。

这样问题转化为:

需要从一串数上取间隔为b[i]的两个数进行取反,问最少多少次把整个串变成0

然后我们再看,如果把每次操作视为一次移动,即把一段长度为b[i]左端点的数移动到右端点+1并与之相抑或。若两者都是1,则相消,若一个是1,一个是0,则可看作移动,两个都是0,则可以看作不动。这样,问题转化成:

在一个有n个节点的无向图中,每个节点连m条边,你要找到每一个1移动到另一个1的最短距离,求总的最短距离

这样的话可以用spfa(其实直接bfs也可以,以为不用去再更新之前的点的距离)求最短路。预处理出每个最短路因此我们可以发现用状压比较好解决,压的是不超过2×k个1的状态。

再提一下,在进行状压的时候,不用顾及前面枚举过的点,那些点的值已经处理好了,因此直接先找到你要取的点,即NUM1+1,从这一个开始枚举后面的是1的点就行。

  1. 1 #include<bits/stdc++.h>
  2. 2 #define r(X) scanf("%d",&X)
  3. 3 #define w(X) printf("%d\n",X)
  4. 4 using namespace std;
  5. 5
  6. 6 int n,k,m,b[70];
  7. 7 bool a[60005],vis[60005];
  8. 8 bool nu[60005];//差分
  9. 9 queue<int> q;
  10. 10 vector<int> sh;
  11. 11 int dis[17][60005];//一维只开为1的点
  12. 12 int dp[1<<18];
  13. 13 inline void bfs(){
  14. 14 for(int i=0;i<sh.size();i++){
  15. 15 int st=i,dian=sh[i];
  16. 16 for(int i=0;i<=n;i++) vis[i]=0;
  17. 17 dis[st][dian]=0; vis[st]=true; q.push(dian);
  18. 18 while(!q.empty()){
  19. 19 int x=q.front(); q.pop(); vis[x]=false;
  20. 20 for(int i=1;i<=m;i++){
  21. 21 int y1=x+b[i],y2=x-b[i];
  22. 22 if(y1<=n){
  23. 23 if(dis[st][y1]>dis[st][x]+1){
  24. 24 dis[st][y1]=dis[st][x]+1;
  25. 25 if(!vis[y1]) vis[y1]=true,q.push(y1);
  26. 26 }
  27. 27 }
  28. 28 if(y2>0){
  29. 29 if(dis[st][y2]>dis[st][x]+1){
  30. 30 dis[st][y2]=dis[st][x]+1;
  31. 31 if(!vis[y2]) vis[y2]=true,q.push(y2);
  32. 32 }
  33. 33 }
  34. 34 }
  35. 35 }
  36. 36 }
  37. 37 }
  38. 38
  39. 39 namespace WSN{
  40. 40 inline int main(){
  41. 41 r(n); r(k); r(m);
  42. 42 for(int i=1,x;i<=k;i++) r(x),a[x]=1;
  43. 43 for(int i=1;i<=m;i++) r(b[i]);
  44. 44 n++;
  45. 45 for(int i=1;i<=n;i++){
  46. 46 nu[i]=a[i]^a[i-1];
  47. 47 if(nu[i]) sh.push_back(i);
  48. 48 }
  49. 49 int pot=sh.size();
  50. 50 for(int i=0;i<=pot;i++) for(int j=0;j<=n;j++)
  51. 51 dis[i][j]=99999999;
  52. 52 bfs();
  53. 53 int ti=(1<<pot)-1;
  54. 54 memset(dp,0x3f,sizeof(dp));
  55. 55 dp[0]=0;
  56. 56 for(int sta=0;sta<=ti;sta++){
  57. 57 int num1=0; while((sta&(1<<num1))) num1++;
  58. 58 for(int i=num1+1;i<=pot;i++){
  59. 59 if(!(sta&(1<<i))) dp[sta|1<<i|1<<num1]=min(dp[sta|1<<i|1<<num1],dp[sta]+dis[num1][sh[i]]);
  60. 60 }
  61. 61 }
  62. 62 w(dp[ti]);
  63. 63 return 0;
  64. 64 }
  65. 65 }
  66. 66 signed main(){return WSN::main();}

总结一下这次打挂:

先打暴力,在没打暴力的时候想正解显然是非常弱智的行为(由杠哥大定理可得),

还有就是别被题目的无关题干骗了,觉得是啥就打啥。。。

Noip模拟10 2021.6.27的更多相关文章

  1. Noip模拟63 2021.9.27(考场惊现无限之环)

    T1 电压机制 把题目转化为找那些边只被奇数环包含. 这样的话直接$dfs$生成一棵树,给每个点附上一个深度,根据其他的非树边都是返祖边 可以算出环内边的数量$dep[x]-dep[y]+1$,然后判 ...

  2. Noip模拟84 2021.10.27

    以后估计都是用\(markdown\)来写了,可能风格会有变化 T1 宝藏 这两天老是会的题打不对,还是要细心... 考场上打的是维护\(set\)的做法,但是是最后才想出来的,没有维护对于是没有交. ...

  3. Noip模拟70 2021.10.6

    T1 暴雨 放在第一道的神仙题,不同的做法,吊人有的都在用线段树维护$set$预处理 我是直接$dp$的,可能代码的复杂度比那种的稍微小一点 设$f[i][j][p][0/1]$表示考虑了前$i$列, ...

  4. Noip模拟76 2021.10.14

    T1 洛希极限 上来一道大数据结构或者单调队列优化$dp$ 真就没分析出来正解复杂度 正解复杂度$O(q+nm)$,但是据说我的复杂度是假的 考虑一个点转移最优情况是从它上面的一个反$L$形转移过来 ...

  5. Noip模拟69 2021.10.5

    考场拼命$yy$高精度结果没学好$for$循环痛失$50pts$,当场枯死 以后一定打对拍,要不考后会... T1 石子游戏 首先要知道典型的$NIM$博弈,就是说如果所有堆石子个数的异或和为$0$则 ...

  6. Noip模拟50 2021.9.10

    已经好长时间没有考试不挂分的良好体验了... T1 第零题 开场数据结构,真爽 对于这道题首先要理解对于一条链从上向下和从下向上走复活次数相等 (这可能需要晚上躺在被窝里面脑摸几种情况的样例) 然后就 ...

  7. Noip模拟35 2021.8.10

    考试题目变成四道了,貌似确实根本改不完... 不过给了两个小时颓废时间确实很爽(芜湖--) 但是前几天三道题改着不是很费劲的时候为什么不给放松时间, 非要在改不完题的时候颓?? 算了算了不碎碎念了.. ...

  8. Noip模拟81 2021.10.20

    T1 语言 比较简单的题,然后就瞎写了,所以考场上就我一个写了线段树的,所以我的常数.... 所以就枚举动词的位置,找前面后面有没有出现$4$即可 1 #include<bits/stdc++. ...

  9. Noip模拟83 2021.10.26

    T1 树上的数 有手就能在衡中$OJ$上过,但是$WaitingCoders$不行,就是这样 必须使用$O(n)$算法加上大力卡常,思路就是找子树内没更新的更新,更新过了直接$return$ 1 #i ...

随机推荐

  1. VueJS学习资料大全

    参考:http://www.worktle.com/articles/2467/ 文档&社区 Vue.js官方网站(中文) :http://cn.vuejs.org/ Vue论坛:http:/ ...

  2. weblogic漏洞分析之CVE-2017-3248 & CVE-2018-2628

    CVE-2017-3248 & CVE-2018-2628 后面的漏洞就是2017-3248的绕过而已,所以poc都一样,只是使用的payload不同 本机开启JRMP服务端 ->利用T ...

  3. 1.docker概述及其历史

    一. 为什么会出现docker? 不用说, 肯定是时代进步的产物. 那么, 他为什么能火? 一定是解决了痛点问题. docker也不是一下子就火起来了, 他的火也是有一个过程的, 我们先来看看为什么会 ...

  4. 【敏捷0】敏捷项目管理-为什么从敏捷开始?为什么从PMI-ACP开始?

    作为敏捷项目管理的开篇文章,还是先来简单地说一说为什么先从敏捷开始,为什么是以 PMI-ACP 为参考.当然,这一系列的文章可能不可避免地会为 PMI-ACP 做一些广告,但是我想告诉大家的是,敏捷以 ...

  5. win8 连接到OneDrive时出现问题-感叹号

    显示最后更新时间是1970年... 还有感叹号,没法同步 解决办法: 管理员运行cmd命令: 输入"netsh int ip reset c: esetlog.txt",按下回车键 ...

  6. vue注意点

    template下面只能有一个节点,不能是多个

  7. vscode中tab键无法触发emmet

    在用户自定义处加上一个设置"emmet.triggerExpansionOnTab":true

  8. mac的vssh用sftp连不上,报unexpected SSH2_MSG_UNIMPLEMENTED packet

  9. java 小算法

    //鸡兔同笼 20个头 58腿 for(int a=0;a<=20;a++) { int b = 20-a; if((2*b+4*a)==58) { System.out.println(a+& ...

  10. P7600-[APIO2021]封闭道路【堆,dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P7600 题目大意 给出\(n\)个点的一棵树,边有边权,对于每个\(k\)求去掉最小边权和的点使得每个点的度数都不 ...