前言

考试时候der展了,T1kmp没特判(看来以后还是能hash就hash),T2搜索细节没注意,ans没清零,130飞到14。。。。

T1 匹配(hash/kmp)

这太水了,其实用个hash随便打打就过了,不知道当时想什么非要用个kmp看看那自己的毛片水平到不到位,kmp没写假,特判出问题了。。。。

Note:B加一个字符可能比A短,kmp扫描不到,所以要特判一下:

如果加的字符刚好与A的对应那一位相同,那么整个B就都是A的前缀,那么其x就是lengthB

 1 #include<bits/stdc++.h>
2 using namespace std;
3 int T,nt[300005],la,lb,ans;
4 char ch[3],A[300005],B[300005];
5 inline void kmp(int len){
6 nt[1]=0;
7 for(int i=2,j=0;i<=len;i++){
8 while(j&&B[i]!=A[j+1]) j=nt[j];
9 if(B[i]==A[j+1]) nt[i]=++j;
10 else nt[i]=0;
11 }
12 }
13 namespace WSN{
14 inline int main(){
15 cin>>T;
16 while(T--){
17 memset(nt,0,sizeof(nt));
18 memset(B,0,sizeof(B));
19 cin>>la>>lb;
20 scanf("%s%s",A+1,ch+1);
21 for(int i=1;i<=lb;i++) B[i]=A[i];
22 B[++lb]=ch[1];
23 if(ch[1]==A[lb]){
24 printf("%d\n",lb);
25 continue;
26 }
27 kmp(lb);
28 printf("%d\n",nt[lb]);
29 }
30 return 0;
31 }
32 }
33 signed main(){return WSN::main();}

T2 回家

这题其实你看看就是个tarjan求割点的板子,然而苣蒻的小马只记得有向图缩点tarjan,割点的得用个什么儿子与父亲,剩下的全忘了,于是冲了一发信队,于是。。。

记得

数组和变量都清一次0,保证不会挂(不过时间说不定,但总比WA0强)

30分代码:

 

 1 #include<bits/stdc++.h>
2 using namespace std;
3 inline int read(){
4 int x=0,f=1; char ch=getchar();
5 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
6 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
7 return x*f;
8 }
9 int T,n,m,cnt,ind[800005],save[800005],ans,an[800005];
10 bool vis[800005];
11 struct SNOW{int from,to,next;}; SNOW e[400005<<1]; int r[400005<<1],tot;
12 inline void add(int x,int y){
13 if(x==y) return;
14 for(int i=r[x];i;i=e[i].next) if(e[i].to==y) return;
15 e[++tot]=(SNOW){x,y,r[x]}; r[x]=tot;
16 }
17 bool f;
18 inline bool dfs(int x){
19 // cout<<'x'<<x<<endl;
20 if(x==1) {f=1;return 1;}
21 vis[x]=1;
22 for(int i=r[x];i;i=e[i].next){
23 if(!vis[e[i].to]&&ind[e[i].to]!=0){
24 dfs(e[i].to);
25 }
26 }
27 return f==1? 1:0;
28 }
29 inline int check(int x){
30 for(int i=r[x];i;i=e[i].next)
31 ind[e[i].to]--;
32 ind[x]=0;
33 // cout<<x<<endl;
34 // for(int i=1;i<=n;i++) cout<<ind[i]<<" "; cout<<endl;
35 memset(vis,0,sizeof(vis)); f=0;
36 vis[x]=1;
37 if(dfs(n)) return 0;
38 else return 1;
39 }
40 namespace WSN{
41 inline int main(){
42 T=read();
43 while(T--){
44 memset(r,0,sizeof(r)); tot=0;
45 memset(an,0,sizeof(an)); ans=0;
46 memset(ind,0,sizeof(ind));
47 memset(save,0,sizeof(save));
48 n=read(),m=read();
49 for(int i=1;i<=m;i++){
50 int u=read(),v=read();
51 add(u,v); add(v,u);
52 ind[u]++; ind[v]++;
53 }
54 for(int i=1;i<=n;i++) save[i]=ind[i];
55 // for(int i=2;i<n;i++) if(ind[i]==2) cnt++;
56 // if(cnt==n-2&&ind[1]==1&&ind[n]==1){
57 // printf("%d\n",n-2);
58 // for(int i=2;i<n;i++) printf("%d ",i); putchar('\n');
59 // continue;
60 // }
61 // cout<<check(4)<<endl; continue;
62 for(int i=2;i<n;i++){
63 if(check(i)){ ans++; an[ans]=i; }
64 for(int i=1;i<=n;i++) ind[i]=save[i];
65 }
66 printf("%d\n",ans);
67 if(!ans){ printf("\n");continue; }
68 else{
69 for(int i=1;i<=ans;i++)
70 printf("%d ",an[i]);
71 putchar('\n');
72 }
73 }
74 return 0;
75 }
76 }
77 signed main(){return WSN::main();}

正解是在tarjan求割点上加一两步判断条件,有一种特别的情况,就是:

1
6 6
1 2
2 3
3 4
2 4
3 5
4 6

这组样例画出来就明白了,他1->6必经过3,4;而割点有2,3,4,所以只求割点是不行的

那么加一个vis数组用来记录跑深搜的时候是否经历过这个点,经历过并且符合割点条件的就是答案.

 1 #include<bits/stdc++.h>
2 using namespace std;
3 inline int read(){
4 int x=0,f=1; char ch=getchar();
5 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
6 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
7 return x*f;
8 }
9 int T,n,m,dfn[400005],low[400005],num,root,ans;
10 bool vis[400005],cut[400005];
11 struct SNOW{int to,next;}; SNOW e[800005]; int r[800005],tot;
12 inline void add(int x,int y){
13 if(x==y) return;
14 for(int i=r[x];i;i=e[i].next) if(e[i].to==y) return;
15 e[++tot]=(SNOW){y,r[x]}; r[x]=tot;
16 }
17 inline void tarjan(int x){
18 dfn[x]=low[x]=++num; int flag=0;
19 for(int i=r[x];i;i=e[i].next){
20 int y=e[i].to;
21 if(!dfn[y]){
22 tarjan(y);low[x]=min(low[x],low[y]);
23 if(vis[y]) vis[x]=true;
24 if(low[y]>=dfn[x]){
25 flag++;
26 if((x!=root||flag>1)&&vis[y]&&x!=n&&x!=1)
27 cut[x]=true,ans++;
28 }
29 }else low[x]=min(low[x],dfn[y]);
30 }
31 }
32 namespace WSN{
33 inline int main(){
34 T=read();
35 while(T--){
36 memset(r,0,sizeof(r));
37 memset(dfn,0,sizeof(dfn));
38 memset(low,0,sizeof(low));
39 memset(vis,0,sizeof(vis));
40 memset(cut,0,sizeof(cut));
41 tot=0; num=0; root=1; ans=0;
42 n=read(); m=read();
43 for(int i=1;i<=m;i++){
44 int u=read(),v=read();
45 add(u,v); add(v,u);
46 }
47 vis[n]=1; tarjan(1);
48 printf("%d\n",ans);
49 if(!ans){printf("\n"); continue;}
50 for(int i=2;i<n;i++) if(cut[i]) printf("%d ",i);
51 putchar('\n');
52 }
53 return 0;
54 }
55 }
56 signed main(){return WSN::main();}

T3 寿司(sushi)

思路一:

战神提供的nlogn做法。以每个R为断点记录前缀和B和后缀和B两个数组,可推出一个柿子:

然后将前面的l+r看成整体算出,后面的找规律:

破环成链时将字符串复制一倍,以原字符串长度向右每次移一位。

如果加入一个B,则l-r的值每个都对应-2;

如果加入一个R,则第一组差值取相反数并跑到最后,其余不变并上移一位。

例如:

/*12
BBRBBRBBBRRR
BRBBRBBBRRRB
RBBRBBBRRRBB
BBRBBBRRRBBR
BRBBBRRRBBRB
RBBBRRRBBRBB
BBBRRRBBRBBR
BBRRRBBRBBRB
BRRRBBRBBRBB
RRRBBRBBRBBB
RRBBRBBRBBBR
RBBRBBRBBBRR
2 5|4 3|7 0|7 0|7 0|
1 6|3 4|6 1|6 1|6 1|
0 7|2 5|5 2|5 2|5 2|
2 5|5 2|5 2|5 2|7 0|
1 6|4 3|4 3|4 3|6 1|
0 7|3 4|3 4|3 4|5 2|
3 4|3 4|3 4|5 2|7 0|
2 5|2 5|2 5|4 3|6 1|
1 6|1 6|1 6|3 4|5 2|
0 7|0 7|0 7|2 5|4 3|
0 7|0 7|2 5|4 3|7 0|
0 7|2 5|4 3|7 0|7 0| 一组|中间的的每两个为断点左右绝对值*/

 1 #include<bits/stdc++.h>
2 using namespace std;
3 inline int read(){
4 int x=0,f=1; char ch=getchar();
5 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
6 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
7 return x*f;
8 }
9 int T,numB,ans,tot,frt[1000005],bak[1000005];
10 char s[1000005];
11 namespace WSN{
12 inline int main(){
13 T=read();
14 while(T--){
15 memset(frt,0,sizeof(frt)); tot=1;
16 memset(bak,0,sizeof(bak)); ans=0;
17 numB=0;
18 scanf("%s",s+1);
19 int len=strlen(s+1);
20 for(int i=1;i<=len;i++){
21 if(s[i]=='B')
22 numB++,frt[tot]++;
23 if(s[i]=='R') tot++;
24 }
25 for(int i=1;i<=tot;i++)
26 frt[i]+=frt[i-1], bak[i]=numB-frt[i];
27 for(int i=1;i<tot;i++) cout<<frt[i]<<" "<<bak[i]<<"|";
28 putchar('\n');
29 }
30 return 0;
31 }
32 }
33 signed main(){return WSN::main();}

这样的话还要用大根堆维护,求出每组数差值的变化量以便统计最大的减数(也就是绝对值那一坨)


就在我还在苦思如何使用大根堆时,正解的n复杂度出现了


B哥大定理(BBT)

通过巨量的打表发现规律:只求复制后卡的区间的每个中点求出R向两侧移动的步数的最小值便是最优值。

这样通过维护每一个点的前缀B个数,后缀B个数,前缀R个数,R向左移的步数及向右移的步数,就可O(1)出解

再每中情况去中点扫一遍就行:

 1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 inline int read(){
5 int x=0,f=1; char ch=getchar();
6 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
7 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
8 return x*f;
9 }
10 const int NN=2000005;
11 int T,ans,tot,lb[NN],rb[NN],lr[NN],stl[NN],str[NN],numB;
12 char s[NN];
13 inline int qiu(int l,int mid,int r){
14 return stl[mid]-stl[l-1]-lb[l-1]*(lr[mid]-lr[l-1])+str[mid+1]-str[r+1]-rb[r+1]*(lr[r]-lr[mid]);
15 }
16 namespace WSN{
17 inline int main(){
18 T=read();
19 while(T--){
20 ans=0x3ffffffffffff;
21 scanf("%s",s+1);
22 int len=strlen(s+1);
23 for(int i=1;i<=len;i++) s[i+len]=s[i];
24 len*=2;
25 for(int i=1;i<=len;i++){
26 lb[i]=lb[i-1];
27 lr[i]=lr[i-1];
28 stl[i]=stl[i-1];
29 if(s[i]=='B') lb[i]++;
30 else lr[i]++, stl[i]+=lb[i];
31 }
32 for(int i=len;i>=1;i--){
33 rb[i]=rb[i+1];
34 str[i]=str[i+1];
35 if(s[i]=='B') rb[i]++;
36 else str[i]+=rb[i];
37 }
38 int n=len/2;
39 for(int i=1;i<=n;i++){
40 int mid=(i+i+n-1)>>1;
41 ans=min(ans,qiu(i,mid,i+n));
42 }
43 printf("%lld\n",ans);
44 }
45 return 0;
46 }
47 }
48 signed main(){return WSN::main();}

END

这次考试总觉得应拿到130或稍微第一点,可是呢,失误太多了,以后看到题能用必对的方法就不用拿不准的(总之hash比对)

Noip模拟7 2021.6.11的更多相关文章

  1. Noip模拟74 2021.10.11

    T1 自然数 考场上当我发现我的做法可能要打线段树的时候,以为自己百分之百是考虑麻烦了 但还是打了,还过掉了所有的样例,于是十分自信的就交了 正解还真是线段树,真就第一题数据结构 但是包括自己造的小样 ...

  2. Noip模拟36 2021.8.11

    刚题的习惯还是改不了,怎么办??? T1 Dove打扑克 考场上打的动态开点线段树+并查集,考后发现自己像一个傻子,并查集就行.. 这几天恶补数据结构疯了 用树状数组维护后缀和,$siz_i$表示编号 ...

  3. Noip模拟50 2021.9.10

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

  4. Noip模拟70 2021.10.6

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

  5. Noip模拟76 2021.10.14

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

  6. Noip模拟69 2021.10.5

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

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

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

  8. Noip模拟61 2021.9.25

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

  9. Noip模拟59 2021.9.22

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

随机推荐

  1. Prism+WPF使用DependencyInjection实现AutoMapper的依赖注入功能

    前言 在使用PRISM+WPF开发项目的过程中,需要使用AutoMapper实现对象-对象的映射功能.无奈PRISM没有相关对AutoMapper相关的类库,于是转换一下思想,在nuget 中存在有关 ...

  2. [第六篇]——云服务器之Spring Cloud直播商城 b2b2c电子商务技术总结

    云服务器 云服务器(Elastic Compute Service, ECS)是一种简单高效.安全可靠.处理能力可弹性伸缩的计算服务. 云服务器管理方式比物理服务器更简单高效,我们无需提前购买昂贵的硬 ...

  3. golang 注释 exported function xxx should have comment or be unexported

    0x00 问题 exported function xxx should have comment or be unexported. 0x01 解决 https://golang.org/s/sty ...

  4. STM32,下载HAL库写的代码后J-Link识别不到芯片,必须要按住复位才能下载?

    问题描述:最近在学STM32的HAL库,据说可以统一STM32江湖,前途无量.最近一段时间参照STM32CubeMX和原子的资料自己学着建了两个HAL库的工程模板,F4的还好说,F1的出现了一个玄学问 ...

  5. PHP的rar解压读取扩展包学习

    作为压缩解压方面的扩展学习,两大王牌压缩格式 rar 和 zip 一直是计算机领域的压缩终结者.rar 格式的压缩包是 Windows 系统中有接近统治地位的存在,今天我们学习的 PHP 扩展就是针对 ...

  6. linux7可以通过远程和localhost访问mysql,但是127.0.0.1不能访问

    网上搜索的其他方法都试过,不行 比如设置权限,开放端口,配置数据库... 最好偶然一个搜索查看可能原因是防火墙端口问题: vim /etc/sysconfig/iptables 在文件中添加下面语句 ...

  7. php升级版本后的影响5.5->7.1

    微信开发中之前常用到$GLOBALS['HTTP_RAW_POST_DATA'] ,但升级后这个参数不见了,导致了一系列错误, 可以用 file_get_contents('php://input') ...

  8. 转mybatis返回自增主键,亲测

    重点是获取对象的主键值而不是insert的返回值 Mybatis获取插入数据的主键时,返回值总是1xml里的写法 第一种方式 <insert id="insertLogin" ...

  9. deecms栏目页调用自定义字段方法

    {dede:arclist addfields='suoxu_jifen,shichang_jiage' typeid='13' row='15' channelid='3'} <li>& ...

  10. Linux系列(21) - 光盘、U盘挂载

    挂载光盘 mount命令.umount命令 step-1 建立挂载点 原理:相当于建立盘符,建个目录读取光盘内容 命令:[root@localhost ~]# mkdir /mnt/cdrom/ 备注 ...