T1 string(线段树优化)

看到数据范围就必须要想到优化,那么如何把26×M∗N 的复杂度降低呢??

用到那个我们最不想打的数据结构——线段树。。。。。。

然而,这个线段树与往常不同,他只需要用lazy下标,这样的话,也会比往常的码量稍微小点

(听别人说,这提可能还需要卡常)

不说了,代码表示比较明白

  1.  

  1. 1 #include<bits/stdc++.h>
  2. 2 #define lid (id<<1)
  3. 3 #define rid (id<<1|1)
  4. 4 using namespace std;
  5. 5 inline int read(){
  6. 6 int x=0,f=1; char ch=getchar();
  7. 7 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
  8. 8 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
  9. 9 return x*f;
  10. 10 }
  11. 11 int n,m,summ[27];char s[100005];
  12. 12 struct tree{
  13. 13 int l,r,sum,lazy;
  14. 14 }; tree t[100005<<2];
  15. 15 inline void pushup(int id){
  16. 16 if(t[lid].sum==t[rid].sum) t[id].sum=t[lid].sum;
  17. 17 else t[id].sum=-1;
  18. 18 }
  19. 19
  20. 20 inline void pushdown(int id){
  21. 21 if(t[id].sum!=-1) t[lid].sum=t[rid].sum=t[id].sum;
  22. 22 }
  23. 23
  24. 24 inline void bt(int id,int l,int r){
  25. 25 t[id].l=l; t[id].r=r; t[id].sum=-1;
  26. 26 if(l==r){ t[id].sum=s[l]-'a'; return; }
  27. 27 int mid=(l+r)>>1;
  28. 28 bt(lid,l,mid);
  29. 29 bt(rid,mid+1,r);
  30. 30 pushup(id);
  31. 31 }
  32. 32
  33. 33 inline void add(int id,int l,int r){
  34. 34 if(t[id].l>=l&&t[id].r<=r){
  35. 35 if(t[id].sum!=-1){
  36. 36 summ[t[id].sum]+=t[id].r-t[id].l+1;
  37. 37 return;
  38. 38 }
  39. 39 }
  40. 40 pushdown(id);
  41. 41 int mid=(t[id].l+t[id].r)>>1;
  42. 42 if(l<=mid) add(lid,l,r);
  43. 43 if(mid+1<=r) add(rid,l,r);
  44. 44 }
  45. 45
  46. 46 inline void change(int id,int l,int r,int v){
  47. 47 if(l>r) return;
  48. 48 if(t[id].l>=l&&t[id].r<=r){ t[id].sum=v; return;}
  49. 49 int mid=(t[id].l+t[id].r)>>1;
  50. 50 if(l<=mid) change(lid,l,r,v);
  51. 51 if(mid+1<=r) change(rid,l,r,v);
  52. 52 pushup(id);
  53. 53 }
  54. 54
  55. 55 inline void qu(int id){
  56. 56 if(t[id].sum!=-1){
  57. 57 for(int i=1;i<=t[id].r-t[id].l+1;i++)
  58. 58 putchar(t[id].sum+'a');
  59. 59 return;
  60. 60 }
  61. 61 qu(lid);
  62. 62 qu(rid);
  63. 63 }
  64. 64 namespace WSN{
  65. 65 inline int main(){
  66. 66 n=read(),m=read();
  67. 67 scanf("%s",s+1);
  68. 68 bt(1,1,n);
  69. 69 while(m--){
  70. 70 memset(summ,0,sizeof(summ));
  71. 71 int l=read(),r=read(),x=read();
  72. 72 add(1,l,r);
  73. 73 if(x==1){
  74. 74 int ll=l;
  75. 75 for(int i=0;i<=25;i++){
  76. 76 change(1,ll,ll+summ[i]-1,i);
  77. 77 ll+=summ[i];
  78. 78 }
  79. 79 }
  80. 80 if(x==0){
  81. 81 int ll=l;
  82. 82 for(int i=25;i>=0;i--){
  83. 83 change(1,ll,ll+summ[i]-1,i);
  84. 84 ll+=summ[i];
  85. 85 }
  86. 86 }
  87. 87 }
  88. 88 qu(1);
  89. 89 return 0;
  90. 90 }
  91. 91 }
  92. 92 signed main(){return WSN::main();}

T2 Matrix(Dp)

首先说一下,当这个题我看到dp方程表示的含义时,就吐了。。。这什么鬼才想出来的??? %%cbx

dp[i][j]表示在扫描到第i列时右区间的左端点在第i列左侧的个数是j,数组反映方案数。

唉,这大长定语我身为语文弱者已经尽力了。。。

数组l,r分别表示左区间的右端点在1~l间的个数:右区间的左端点在1~r间的个数,相当于维护一个前缀和

先考虑左区间:

扫描过一列后,扫面下一列而l[i]==l[i-1],表示该列无新的扫描完的左区间: f[i][j]=f[i1-][j]

扫描过一列后,扫面下一列而l[i]!=l[i-1],表示该列有新的扫描完的左区间:

 总共有 l[i]−l[i−1]个左区间需要安排 1 ,之前还空着的列有 i−j−l[i−1] 个,所以安排左区间的方案数为

    $P^{l[i]-l[i-1]}_{i-j-l[i-1]}$

再考虑右区间:

j>0,则f[i][j]可以由f[i-1][j-1]转移而来。总共r[i]行,放了j-1行,还剩r[i]-(j-1)行:

    $f [ i ][ j ]+=f [ i - 1 ][ j-1 ]*[r[i]-(j-1)]*P^{l[i]-l[i-1]}_{i-j-l[i-1]}$

  1. 1 #include<bits/stdc++.h>
  2. 2 #define int long long
  3. 3 using namespace std;
  4. 4 inline int read(){
  5. 5 int x=0,f=1; char ch=getchar();
  6. 6 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
  7. 7 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
  8. 8 return x*f;
  9. 9 }
  10. 10 const int NN=3002,p=998244353;
  11. 11 int n,m,l[NN],r[NN],f[NN][NN];
  12. 12 namespace WSN{
  13. 13 inline int main(){
  14. 14 f[0][0]=1;
  15. 15 n=read(),m=read();
  16. 16 for(int i=1;i<=n;i++){
  17. 17 int L=read(),R=read();
  18. 18 l[L]++,r[R]++;
  19. 19 }
  20. 20 for(int i=1;i<=m;i++){
  21. 21 f[i][0]=f[i-1][0];
  22. 22 l[i]+=l[i-1];
  23. 23 r[i]+=r[i-1];
  24. 24 for(int j=1;j<=i;j++)
  25. 25 f[i][j]=(f[i-1][j]+f[i-1][j-1]*(r[i]-(j-1))%p)%p;
  26. 26 for(int k=0;k<=i;k++)
  27. 27 for(int j=l[i-1];j<l[i];j++)
  28. 28 f[i][k]=f[i][k]*(i-j-k)%p;
  29. 29 }
  30. 30 printf("%lld\n",f[m][n]);
  31. 31 return 0;
  32. 32 }
  33. 33 }
  34. 34 signed main(){return WSN::main();}

T3 Big (trie树)

巧妙的将复杂的函数取模柿子转化为理解的懂得柿子:

前面的地板函数模完2^n后值域是0和1,后面加上2x并模一个2^n意思是向左移一位加起来就是相当于将原数的二进制首位推到末尾,其他位向前移动一位,举个不是二进制的例子

1234----->> 2341

这样,我们就可以明显的发现这是一道trie树题

我们以对手的操作为断点,前面会让x xor一些数,操作后也会xor,这样,我们可以记录前缀和,枚举对手操作的各种断点,这样就可以找到最优解了

再提一下的就是分情况

一节点有两个孩子,那么无论我们如何构造x,对手一定能将这一位变为0,所以答案这一位为0

 如果只有一个儿子,那么我们一定可以构造出一个x,使答案的这一位为1,所以答案这一位为1。

所以一边记录最大值一边统计个数就完了

  1. 1 #include<bits/stdc++.h>
  2. 2 #define X ((x>>(i-1))&1)
  3. 3 using namespace std;
  4. 4 inline int read(){
  5. 5 int x=0,f=1; char ch=getchar();
  6. 6 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
  7. 7 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
  8. 8 return x*f;
  9. 9 }
  10. 10 const int NN=300005;
  11. 11 int n,m,ch[8000000][3],tot=1,a[NN],s[NN],ans1,ans2;
  12. 12 inline int change(int x){return (x>>(n-1))+((x&(~(1<<(n-1))))<<1);}
  13. 13 //attacker use problem idea to change the number
  14. 14 inline void insert(int x){
  15. 15 int u=1;
  16. 16 for(int i=n;i>=1;i--){
  17. 17 if(!ch[u][X]) ch[u][X]=++tot;
  18. 18 u=ch[u][X];
  19. 19 }
  20. 20 }
  21. 21 inline void dfs(int u,int x,int len){
  22. 22 if(len==0){
  23. 23 if(x>ans1){
  24. 24 ans1=x;
  25. 25 ans2=1;
  26. 26 }else if(x==ans1) ans2++;
  27. 27 return;
  28. 28 }
  29. 29 if(ch[u][0]&&ch[u][1]){
  30. 30 dfs(ch[u][0],x,len-1);
  31. 31 dfs(ch[u][1],x,len-1);
  32. 32 }
  33. 33 if(ch[u][0]&&!ch[u][1]) dfs(ch[u][0],(x|(1<<(len-1))),len-1);
  34. 34 if(ch[u][1]&&!ch[u][0]) dfs(ch[u][1],(x|(1<<(len-1))),len-1);
  35. 35 }
  36. 36 namespace WSN{
  37. 37 inline int main(){
  38. 38 n=read(),m=read();//n mean the length of "2 jinzhi"
  39. 39 for(int i=1;i<=m;i++) a[i]=read();
  40. 40 for(int i=1;i<=m;i++) s[i]=s[i-1]^a[i];//xor "qian z s[m]^s[i]));
  41. 41 for(int i=0;i<=m;i++) insert(change(s[i])^(s[m]^s[i]));
  42. 42 dfs(1,0,n);
  43. 43 printf("%d\n%d\n",ans1,ans2);
  44. 44 return 0;
  45. 45 }
  46. 46 }
  47. 47 signed main(){return WSN::main();}

END

这次考试还是有小问题,就是时间分配不均。

超级有自信的打过了T4,然而也花费了超级多的时间,结果是T4没有拿到满分,前面题也顾不上做,幸好前面的题整体得分不高,而我的第四题想的也是正解思路,总之不亏吧~~

再%%XIN考试全场首A第四题太强了

Noip模拟5 2021.6.7的更多相关文章

  1. Noip模拟70 2021.10.6

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

  2. Noip模拟76 2021.10.14

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

  3. Noip模拟69 2021.10.5

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

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

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

  5. Noip模拟61 2021.9.25

    T1 交通 考场上想了一个$NPC$.应该吧,是要求出图里面的所有可行的不重复欧拉路 无数种做法都无法解出,时间也都耗在这个上面的,于是就考的挺惨的 以后要是觉得当前思路不可做,就试着换一换思路,千万 ...

  6. Noip模拟59 2021.9.22

    新机房首模拟变倒数 T1 柱状图 关于每一个点可以做出两条斜率分别为$1,-1$的直线, 然后题意转化为移动最少的步数使得所有点都在某一个点的两条直线上 二分出直线的高度,判断条件是尽量让这条直线上部 ...

  7. Noip模拟52 2021.9.13

    T1 异或 比较稳的切掉 观察数据范围,无法线性筛啥的,根号复杂度也会死,于是只能考虑$log$级 然后打表 发现当$n$为$2^i$时的答案是一个可递归数列: $1,3,7,15,31,63,127 ...

  8. Noip模拟51 2021.9.12

    T1 茅山道术 考场上卡在了一个恶心的地方, 当时以为每次施法都会产生新的可以施法的区间,然后想都没细想, 认为不可做,甚至$dfs$也无法打,考后一问发现是自己想多了.. 新产生的区间对答案根本没有 ...

  9. Noip模拟50 2021.9.10

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

  10. Noip模拟49 2021.9.7

    T1 reverse 又一道板子打假的挂分题,直接挂到倒二.. 考场上思路神奇,居然想到用$bfs$建边然后跑最短路, 其实当时也想到了直接$bfs$,但是不知道为啥觉得$dij$屌就没直接打$bfs ...

随机推荐

  1. iNeuOS工业互联平台,PLC监测与控制应用过程案例。新闻:.NET 6 RC1 正式发布

    目       录 1.      概述... 1 2.      平台演示... 2 3.      应用过程... 2 1.   概述 iNeuOS工业互联网操作系统主要使用.netcore 3. ...

  2. jquery获取一个元素符合条件的第一个父元素

    closest jQuery 1.3新增.从元素本身开始,逐级向上级元素匹配,并返回最先匹配的元素.. closest会首先检查当前元素是否匹配,如果匹配则直接返回元素本身.如果不匹配则向上查找父元素 ...

  3. 开源ASR服务器vosk

    概述 近几年由于AI的迅速发展,语音相关的自然语言处理NLP项目也变多了,新的技术也越来越成熟,其中TTS(语音生成)和ASR(语音识别)是NLP中非常重要的环节. 今天我们介绍一个开源的ASR项目v ...

  4. Dapr + .NET Core实战(四)发布和订阅

    什么是发布-订阅 发布订阅是一种众所周知并被广泛使用的消息传送模式,常用在微服务架构的服务间通信,高并发削峰等情况.但是不同的消息中间件之间存在细微的差异,项目使用不同的产品需要实现不同的实现类,虽然 ...

  5. oracle 基础SQL语句 版本5.7.29

    一.表与用户介绍 oracle安装完成后默认会有很多用户,大致分为2类用户:一类是必需的帐户,一类是存储各种应用的帐户,默认密码如下: oracle自带的也会有很多默认表存在: 二.创建用户.创建表空 ...

  6. Appium+Python自动化环境搭建-1

    前言 appium可以说是做app最火的一个自动化框架,它的主要优势是支持android和ios,另外脚本语言也是支持java和Python. 小编擅长Python,所以接下来的教程是appium+p ...

  7. 在windoes server2008部署kettle遇到的问题

    本机电脑是windows10,在部署ketle时一切顺利,但在windows server2008服务器上部署,各种报错,毕竟线上环境比较复杂-- 问题一:启动kettle的spoon.bat文件时, ...

  8. 前端快闪三:多环境灵活配置react

    你已经使用Create React App脚手架搭建了React应用,现在该部署了. 一般会使用npm run build或者yarn build构建出静态资源, 由web服务器承载. 您会体验到 多 ...

  9. virtualbox nat 模式下连接虚拟机redis

    主要是使用端口转发的方法 如果你能使用xshell等工具连接这个方法基本一样  接着修改redis.conf文件的69 行(我使用的是5.0)将这里的地址修改为虚拟机的 ip 地址,这里我使用的是备份 ...

  10. Serverless 的初心、现状和未来

    作者 | 不瞋 导读:Serverless 是如何产生的?当前有哪些落地场景?Serverless 的未来又将如何?本文分享了阿里云高级技术专家不瞋对于 Serverless 的看法,回顾其发展历程, ...