Noip模拟53 2021.9.14
T1 ZYB和售货机
首先这道题有两种做法。
一种是发现每个点都可以先被取到只剩一个,只要收益大于$0$
然后发现建一个$i->f[i]$的图时出现环,要把它去掉,
那么跑一个$tarjan$枚举每一个强联通分量然后找到收益获得最少的边删掉就行
第二种做法是建立两个数组$mx[f[i]],nx[f[i]]$分别表示对于连向$f[i]$的边中收益最大和次大的点
那么我们像跳父亲一样$dfs$,找到一个环就比较他们构成环的最大点与次大点里面差值最小的
记录这个点为$x$,那么对于$x$,需要少让他被按一次,让次大点把它按掉,这样就防止了环的影响
实现的话不用这么麻烦,直接记录差值最小值,找到环后直接减掉最小值就行。
1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 namespace AE86{
5 inline int read(){
6 int x=0,f=1;char ch=getchar();
7 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
8 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
9 }inline void write(int x,char opt='\n'){
10 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
11 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
12 for(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
13 }using namespace AE86;
14
15 const int NN=1e5+5,inf=0x3fffffff;
16 int n,f[NN],c[NN],d[NN],a[NN],ans,w[NN];
17 int mx[NN],nx[NN],cer[NN],minn,num;
18
19 inline void dfs(int x){
20 if(cer[x]==num){ans-=minn;return;}
21 if(cer[x]) return;
22 cer[x]=num;
23 if(!mx[x]) return;
24 ans+=w[mx[x]]*a[x];
25 minn=min(minn,w[mx[x]]-w[nx[x]]);
26 if(mx[x]!=x) dfs(mx[x]);
27 }
28
29 namespace WSN{
30 inline short main(){
31 freopen("goods.in","r",stdin);
32 freopen("goods.out","w",stdout);
33 n=read();
34 for(int i=1;i<=n;i++)
35 f[i]=read(),c[i]=read(),d[i]=read(),a[i]=read();
36 for(int i=1;i<=n;i++){
37 w[i]=d[f[i]]-c[i];
38 if(w[mx[f[i]]]<w[i])
39 nx[f[i]]=mx[f[i]],mx[f[i]]=i;
40 else if(w[nx[f[i]]]<w[i]) nx[f[i]]=i;
41 }
42 for(int i=1;i<=n;i++) if(!cer[i])
43 minn=inf,++num,dfs(i);
44 write(ans);
45 return 0;
46 }
47 }
48 signed main(){return WSN::main();}
T2 ZYB玩字符串
发现每个最终的$S$里面必定有至少一个初始串$p$。
考虑枚举初始串长度,然后枚举可能的$p$,这几步正解暴力都一样
然后,如果要是打成了暴力,就会是每次暴力$check$,看看这个$p$是否能把$S$消没
你发现你只有$20$,观察测试点会有一个$ababaa$,这个卡掉了正着枚举哈希判断的你
于是你再反着做一边,得到了$50$,跟刚才的其实一样,只不过是他不把那个东西放在后边,而是中间,于是你只能打正解
关于判断,我们考虑$dp$,设$f[i][j]$表示从$[i,j]$这段区间是否合法
如果$j-i+1$是$len$的倍数,就表示$f[i][j]$区间能否被消灭
对于不是$len$倍数的区间,合法表示他有一段$p$的前缀以及若干段$p$,
那么
$1.f_{i,j}|=f_{i,j-1}\& \left [ s[j]==t[(j-i) \mod len+1] \right ] $
表示凑出前缀
$2. f_{i,j}|=f_{i,j-k*len} \& f_{j-k*len+1,j} $
表示凑出若干段$p$
然后可以记忆化,可以直接循环
有个问题需要请教:(已解决,自己弱智了)
关于代码里面的取%问题。
把取%函数去掉直接使用 $\textit{ t[((r-l+1)%len)] }$
他就一个合法的$check$也没有
使用取%函数 $\textit{ t[mo(r-l+1,len)] }$
他就对了。
inline int mo(int x,int y){
return x>y?mo(x-y,y):x;
}
非常不懂,请路过的大佬帮助苣蒻
1 #include<bits/stdc++.h>
2 using namespace std;
3 const int NN=205;
4 int T,n,tot,a[NN],t[NN],ans[NN];
5 char s[NN];
6 int f[NN][NN];
7 inline int mo(int x,int y){
8 return x>y?mo(x-y,y):x;
9 }
10 inline bool dfs(int len,int l,int r){
11 if(l>r) return 1;
12 if(f[l][r]!=-1) return f[l][r];
13 for(int mid=r-len;mid>=l;mid-=len)
14 if(dfs(len,l,mid)&&dfs(len,mid+1,r)) return f[l][r]=1;
15 if(a[r]==t[mo(r-l+1,len)]) return f[l][r]=dfs(len,l,r-1);
16 return f[l][r]=0;
17 }
18
19 namespace WSN{
20 inline short main(){
21 freopen("string.in","r",stdin);
22 freopen("string.out","w",stdout);
23 cin>>T;
24 while(T--){
25 scanf("%s",s+1); n=strlen(s+1);
26 tot=0; memset(ans,0,sizeof(ans));
27 for(int i=1;i<=n;i++) a[i]=(int)s[i]-'a'+1;
28 for(int len=1;len<=n;len++){
29 if(n%len) continue;
30 for(int l=1;l<=n-len+1;l++){
31 memset(f,-1,sizeof(f));
32 for(int i=l;i<=l+len-1;i++) t[i-l+1]=a[i];
33 // printf("len=%d l=%d r=%d check=%d\n",len,l,l+len-1,dfs(len,1,n));
34 if(dfs(len,1,n)){
35 if(!tot){
36 tot=len;
37 for(int i=1;i<=tot;i++) ans[i]=t[i];
38 }else{
39 for(int i=1;i<=tot;i++) if(ans[i]>t[i]){
40 for(int j=1;j<=tot;j++) ans[j]=t[j];
41 break;
42 }
43 }
44 }
45 }
46 if(tot) break;
47 }
48 for(int i=1;i<=tot;i++) printf("%c",ans[i]+'a'-1); puts("");
49 }
50 return 0;
51 }
52 }
53 signed main(){return WSN::main();}
T3 午餐
最短路神题
题解不知道在说什么,反正我是看完$DeepinC$博客才看懂的题解,于是。。。
(感谢学长花大力气打出如此详细的题解)
理解过之后就可以搞出来了
1 #include<bits/stdc++.h>
2 #define fi first
3 #define se second
4 #define mp make_pair
5 #define pii pair<int,int>
6 using namespace std;
7 namespace AE86{
8 inline int read(){
9 int x=0,f=1;char ch=getchar();
10 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
11 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
12 }inline void write(int x,char opt='\n'){
13 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
14 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
15 for(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
16 }using namespace AE86;
17
18 const int NN=2e5+5,inf=0x3fffffff;
19 int n,m,a[NN],f[NN],st[NN],ed[NN],h[NN],L[NN],R[NN];
20 struct SNOW{int to,l,r,next;}e[NN<<1]; int head[NN],rp;
21 inline void add(int x,int y,int l,int r){
22 e[++rp]=(SNOW){y,l,r,head[x]}; head[x]=rp;
23 e[++rp]=(SNOW){x,l,r,head[y]}; head[y]=rp;
24 }
25 struct node{
26 int id,data;
27 friend bool operator<(node a,node b){
28 return a.data<b.data;
29 }
30 }; priority_queue<node> Q;
31 priority_queue<pii > q;
32 bool vis[NN];
33
34 inline void dij(){
35 memset(f,0x3f,sizeof(f));
36 Q.push((node){1,0}); f[1]=0;
37 while(!Q.empty()){
38 int x=Q.top().id,y=Q.top().data; Q.pop();
39 for(int i=head[x];i;i=e[i].next){
40 int y=e[i].to,val=max(h[y]+1,max(f[x],e[i].l));
41 if(f[y]>val&&val<=e[i].r)
42 Q.push((node){y,f[y]=val});
43 }
44 }
45 }
46
47 namespace WSN{
48 inline short main(){
49 freopen("lunch.in","r",stdin);
50 freopen("lunch.out","w",stdout);
51 n=read(); m=read();
52 for(int i=1;i<=m;i++){
53 int u=read(),v=read(),l=read(),r=read();
54 add(u,v,l,r); st[i]=u; ed[i]=v; L[i]=l; R[i]=r;
55 }
56 for(int i=1;i<=n;i++){
57 a[i]=read(); if(a[i]!=-1) h[i]=-1;
58 else q.push(mp(h[i]=inf,i));
59 }
60 while(!q.empty()){
61 int x=q.top().se,y=q.top().fi; q.pop();
62 for(int i=head[x];i;i=e[i].next)
63 if(h[x]>=e[i].r && h[e[i].to]<e[i].l)
64 q.push(mp(h[e[i].to]=e[i].l,e[i].to));
65 }
66 if(h[1]>0) return puts("Impossible"),0; dij();
67 for(int i=1;i<=n;i++) if(a[i]==1&&f[i]>1e9){
68 return puts("Impossible"),0;
69 }
70 for(int i=1;i<=m;i++){
71 int u=st[i],v=ed[i],l=L[i],r=R[i];
72 if(f[u]>r||f[v]>r){write(l);continue;}
73 write(max(l,max(f[u],f[v])));
74 }
75 return 0;
76 }
77 }
78 signed main(){return WSN::main();}
T4 计数
考场上打了一个$m=0$的卡特兰数就跑了。。。。
但是发现考后$20$分的居然都是$TLE$,(反正我不会打暴力)
所以我随口说一下,关于二叉树的种类问题是$Cat_n=C_{2n}^{n}-C_{2n}^{n-1}$
但是这和正解毫不相关
正解考虑二叉树的前序遍历性质:
- 这棵树的编号满足小根堆性质
- 这棵树的某个子树编号连续,为$[root,root+size-1]$
- 这棵树左子树节点编号都小于右子树
- 这棵树任意一个有左子节点的节点的左子节点编号必定为该节点编号$+1$
说白了就是$dfs$序。但是$rvalue$学长总结的好就抄过来了
关于中序遍历的限制,每个点对会被强制规定一个限制,考虑以前序遍历表示的点对$(a,b)$
如果限制a在b后,a一定是b的祖先
限制a在b前,两种位置关系都有可能
发现这两种限制实际上就是在限制以一个点为根的字数大小
如果$a>b$那么会卡$b$的下限,反之卡$a$的上限
所以可以预处理出每个点的子树大小上限和下限然后记忆化
1 #include<bits/stdc++.h>
2 using namespace std;
3 namespace AE86{
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();}return x*f;
8 }inline void write(int x,char opt='\n'){
9 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
10 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
11 for(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
12 }using namespace AE86;
13
14 const int mod=1e9+7;
15 int T,n,m,lml[405],lmr[405];
16 int C[805][805],dp[405][405];
17 inline int mo(int x){return x>=mod?x-mod:x;}
18 inline void pre(){
19 C[0][0]=1;
20 for(int i=1;i<=800;i++){
21 C[i][0]=C[i][i]=1;
22 for(int j=1;j<i;j++){
23 C[i][j]=mo(C[i-1][j]+C[i-1][j-1]);
24 }
25 }
26 }
27 inline int Catlan(int n){
28 return mo(C[n*2][n]-C[n*2][n-1]+mod);
29 }
30
31 inline int dfs(int x,int siz){
32 if(dp[x][siz]!=-1) return dp[x][siz];
33 if(!siz) return dp[x][siz]=1;
34 dp[x][siz]=0;
35 for(int i=lml[x];i<=lmr[x]&&i<siz;i++)
36 dp[x][siz]=mo(dp[x][siz]+1ll*dfs(x+1,i)*dfs(x+1+i,siz-1-i)%mod);
37 return dp[x][siz];
38 }
39
40 namespace WSN{
41 inline short main(){
42 freopen("count.in","r",stdin);
43 freopen("count.out","w",stdout);
44 T=read(); pre();
45 while(T--){
46 n=read(); m=read();
47 if(!m) {write(Catlan(n));continue;}
48 memset(dp,-1,sizeof(dp));
49 for(int i=1;i<=n;i++) lml[i]=0,lmr[i]=n-i+1;
50 for(int i=1;i<=m;i++){
51 int a=read(),b=read();
52 if(a>b) lml[b]=max(lml[b],a-b);
53 else lmr[a]=min(lmr[a],b-a-1);
54 }
55 write(dfs(1,n));
56 }
57 return 0;
58 }
59 }
60 signed main(){return WSN::main();}
Noip模拟53 2021.9.14的更多相关文章
- Noip模拟76 2021.10.14
T1 洛希极限 上来一道大数据结构或者单调队列优化$dp$ 真就没分析出来正解复杂度 正解复杂度$O(q+nm)$,但是据说我的复杂度是假的 考虑一个点转移最优情况是从它上面的一个反$L$形转移过来 ...
- Noip模拟39 2021.8.14
T1 打地鼠 都切掉了的简单题 1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 con ...
- Noip模拟15 2021.7.14
T1 夜莺与玫瑰 题目越发的变态起来... 这题刚开始看超级像仪仗队,好不容易码完欧拉函数后尝试×2后输出但不对!! 于是选择了跳过.... 正解居然是莫比乌斯函数....我也是醉了 预处理完就剩下$ ...
- 2021.9.14考试总结[NOIP模拟53]
T1 ZYB和售货机 容易发现把每个物品都买成$1$是没有影响的. 然后考虑最后一个物品的方案,如果从$f_i$向$i$连边,发现每个点有一个出度多个入度,可以先默认每个物品都能买且最大获利,这样可以 ...
- Noip模拟70 2021.10.6
T1 暴雨 放在第一道的神仙题,不同的做法,吊人有的都在用线段树维护$set$预处理 我是直接$dp$的,可能代码的复杂度比那种的稍微小一点 设$f[i][j][p][0/1]$表示考虑了前$i$列, ...
- Noip模拟69 2021.10.5
考场拼命$yy$高精度结果没学好$for$循环痛失$50pts$,当场枯死 以后一定打对拍,要不考后会... T1 石子游戏 首先要知道典型的$NIM$博弈,就是说如果所有堆石子个数的异或和为$0$则 ...
- Noip模拟63 2021.9.27(考场惊现无限之环)
T1 电压机制 把题目转化为找那些边只被奇数环包含. 这样的话直接$dfs$生成一棵树,给每个点附上一个深度,根据其他的非树边都是返祖边 可以算出环内边的数量$dep[x]-dep[y]+1$,然后判 ...
- Noip模拟61 2021.9.25
T1 交通 考场上想了一个$NPC$.应该吧,是要求出图里面的所有可行的不重复欧拉路 无数种做法都无法解出,时间也都耗在这个上面的,于是就考的挺惨的 以后要是觉得当前思路不可做,就试着换一换思路,千万 ...
- Noip模拟59 2021.9.22
新机房首模拟变倒数 T1 柱状图 关于每一个点可以做出两条斜率分别为$1,-1$的直线, 然后题意转化为移动最少的步数使得所有点都在某一个点的两条直线上 二分出直线的高度,判断条件是尽量让这条直线上部 ...
随机推荐
- 制作Windows服务和安装程序(C#版)
http://blog.sina.com.cn/s/blog_5f4ffa170100vt2b.html 1.创建服务项目: 打开VS 2005 编程环境,在C#中新建Windows服务程序 2.将安 ...
- HDU 6170 Two strings( DP+字符串匹配)
http://acm.hdu.edu.cn/showproblem.php?pid=6170 题目大意: 给出两个字符串s1和s2(长度小于等于2500). s1是一个正常的包含大小写字母的字符串,s ...
- leetcode 盛水最多的容器 解析
采用双指针法: 主要思想:定义头尾两个指针,分别向中间遍历,当相遇时结束循环.存储每一次遍历容器盛水的最大容量,并不断更新. 盛水的最大容量为 左右指针高度的最小值 乘以 左右指针的距离即宽度. 则可 ...
- mysql语句alter添加 字段
alter table ylh_coupon add is_reg int default 0 给数据表 ylh_coupon 添加一个字段 is_reg,,整型,默认值为0
- 带你掌握Vue过滤器filters及时间戳转换
摘要:Vue的filters过滤器是比较常见的一个知识点,下面我将结合时间戳转换的例子带你快速了解filters的用法. 本文分享自华为云社区<三分钟掌握Vue过滤器filters及时间戳转换& ...
- (转载)深入理解MDL元数据锁
作者:MySQL技术本文为作者原创,转载请注明出处:https://www.cnblogs.com/kunjian/p/11993708.html 前言: 当你在MySQL中执行一条SQL时,语句并没 ...
- Shell条件判断(6)- 多重条件判断
多重条件判断 多个条件判断一起使用 测试选项 作用 判断1 -a 判断2 逻辑与,判断1和判断2都成立,最终的结果才为真 判断1 -o 判断2 逻辑或,判断1和判断2有一个成立,最终的结果就为真 ! ...
- c++ 的学习 第3集-默认参数
1.默认参数的意思就是 予以形参默认值 2. C++允许函数设置默认参数,在调用时可以根据情况省略实参.规则如下: 默认参数只能按照右到左的顺序 如果函数同时有声明.实现,默认参数只能放在函数声 ...
- Hive On Spark保姆级攻略
声明: 此博客参考了官网的配置方式,并结合笔者在实践网上部分帖子时的踩坑经历整理而成 这里贴上官方配置说明: [官方]: https://cwiki.apache.org//confluence/di ...
- 分布式、微服务必须配个日志管理系统才优秀,Exceptionless走起~~~
前言 在真实的项目中,不管是功能日志.错误日志还是异常日志,已经是项目的重要组成部分.在原始的单体架构,通常看日志的方式简单粗暴,直接登录到服务器,把日志文件拷贝下来进行分析:而如今分布式.微服务架构 ...