Noip模拟10 2021.6.27
T1 入阵曲
好了,又一个考试败笔题。
也就是在那个时候,小 F 学会了矩阵乘法。让两个矩阵乘几次就能算出斐波那契数, 真是奇妙无比呢。
不过, 小 F 现在可不想手算矩阵乘法——他觉得好麻烦。取而代之的,是一个简单的小问题。
题目清奇的叙述i引起小马清奇的思路——矩阵快速幂优化dp。于是开始了推柿子。。。
一小时,两小时,可恶,还没推出来,唉出来了。。等等,不对。。。
两个半小时将近三小时的时候,算了打暴力吧。。
然后就,唉。
可是这题并非矩阵乘法,草。。。。
那他疯狂diss我干嘛~~
60分很好拿到,不过当时太慌就没打前缀和,n^6暴力直接跑了,惨淡45。。。
正解就是在60暴力上加了一个优化。
he[k]表示两行之间的矩形的前缀和,num[k]表示出现的矩形的对数(记录有几对)。
因为,在模k意义下的前缀和,任取两个矩形前缀和相减必定是k的倍数。
num也就是统计模k相同的矩阵的个数。


1 #include<bits/stdc++.h>
2 #define write(X) printf("%lld",X)
3 #define read(X) scanf("%lld",&X)
4 #define rint register long long
5 #define int long long
6 using namespace std;
7
8 const int NN=1e6+10;
9 int n,m,p,rp;
10 int num[NN],he[NN];
11 int sum[405][405],a[405][405];
12
13 inline void init(){
14 read(n); read(m); read(p);
15 for(rint i=1;i<=n;i++) for(rint j=1;j<=m;j++)
16 read(a[i][j]),a[i][j]%=p;
17 for(rint i=1;i<=n;i++) for(rint j=1;j<=m;j++)
18 sum[i][j]=(sum[i][j-1]+a[i][j])%p;
19 for(rint i=1;i<=n;i++) for(rint j=1;j<=m;j++)
20 sum[i][j]=(sum[i][j]+sum[i-1][j])%p;
21 }
22
23 namespace WSN{
24 inline int main(){
25 init();
26 for(rint i=0;i<n;i++)
27 for(rint j=i+1;j<=n;j++){
28 num[0]=1;
29 for(rint k=1;k<=m;k++){
30 he[k]=(sum[j][k]-sum[i][k]+p)%p;
31 rp+=num[he[k]]++;
32 }
33 for(int k=1;k<=m;k++) num[he[k]]=0;
34 }
35 write(rp); putchar('\n');
36 return 0;
37 }
38 }
39 signed main(){return WSN::main();}
T2 将军令
题目猛一看,这不就是小胖守皇宫吗?不过K的值更大就不会考虑了。。
其实,应该考虑贪心。
从深度最深的点开始向上找他的K级父亲,这样的话从K级父亲开始将能够管到的点全部标记,找就可以了。


1 #include<bits/stdc++.h>
2 #define r(X) scanf("%d",&X)
3 #define w(X) printf("%d\n",X)
4 #define Min(A,B) ((A)<(B)?(A):(B))
5 #define rint register int
6 using namespace std;
7
8 const int NN=1e5+10;
9 int n,k,t,d[NN],fa[NN][25],ans;
10 bool vis[NN];
11 struct SNOW{int to,next;}; SNOW e[NN<<1]; int head[NN],tot;
12 inline void add(int x,int y){ e[++tot]=(SNOW){y,head[x]}; head[x]=tot;}
13 struct snow{
14 int dep,id;
15 }; snow m[NN];
16 inline bool cmp(snow a,snow b){return a.dep>b.dep;}
17
18 inline void dfs1(int f,int x){
19 for(rint i=head[x];i;i=e[i].next){
20 int y=e[i].to;
21 if(y==f) continue;
22 m[y].dep=m[x].dep+1; fa[y][1]=x;
23 for(rint j=2;j<=Min(k,m[y].dep);j++) fa[y][j]=fa[fa[y][j-1]][1];
24 dfs1(x,y);
25 }
26 }
27
28 inline void dfs2(int pre,int x,int tmp){
29 vis[x]=1;
30 if(!tmp) return;
31 for(rint i=head[x];i;i=e[i].next){
32 int y=e[i].to;
33 if(y==pre) continue;
34 dfs2(x,y,tmp-1);
35 }
36 }
37
38 namespace WSN{
39 inline int main(){
40 r(n); r(k); r(t);
41 for(rint i=1,x,y;i<n;i++)
42 r(x),r(y),add(x,y),add(y,x),m[i].id=i;
43 if(k==0) {w(n);return 0;}
44 m[n].id=n;
45 dfs1(0,1);
46 sort(m+1,m+n+1,cmp);
47 for(rint i=1;i<=n;i++) if(!vis[m[i].id]){
48 rint f=fa[m[i].id][k];
49 ans++,dfs2(-1,f,k);
50 }
51 w(ans);
52 return 0;
53 }
54 }
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 #include<bits/stdc++.h>
2 #define r(X) scanf("%d",&X)
3 #define w(X) printf("%d\n",X)
4 using namespace std;
5
6 int n,k,m,b[70];
7 bool a[60005],vis[60005];
8 bool nu[60005];//差分
9 queue<int> q;
10 vector<int> sh;
11 int dis[17][60005];//一维只开为1的点
12 int dp[1<<18];
13 inline void bfs(){
14 for(int i=0;i<sh.size();i++){
15 int st=i,dian=sh[i];
16 for(int i=0;i<=n;i++) vis[i]=0;
17 dis[st][dian]=0; vis[st]=true; q.push(dian);
18 while(!q.empty()){
19 int x=q.front(); q.pop(); vis[x]=false;
20 for(int i=1;i<=m;i++){
21 int y1=x+b[i],y2=x-b[i];
22 if(y1<=n){
23 if(dis[st][y1]>dis[st][x]+1){
24 dis[st][y1]=dis[st][x]+1;
25 if(!vis[y1]) vis[y1]=true,q.push(y1);
26 }
27 }
28 if(y2>0){
29 if(dis[st][y2]>dis[st][x]+1){
30 dis[st][y2]=dis[st][x]+1;
31 if(!vis[y2]) vis[y2]=true,q.push(y2);
32 }
33 }
34 }
35 }
36 }
37 }
38
39 namespace WSN{
40 inline int main(){
41 r(n); r(k); r(m);
42 for(int i=1,x;i<=k;i++) r(x),a[x]=1;
43 for(int i=1;i<=m;i++) r(b[i]);
44 n++;
45 for(int i=1;i<=n;i++){
46 nu[i]=a[i]^a[i-1];
47 if(nu[i]) sh.push_back(i);
48 }
49 int pot=sh.size();
50 for(int i=0;i<=pot;i++) for(int j=0;j<=n;j++)
51 dis[i][j]=99999999;
52 bfs();
53 int ti=(1<<pot)-1;
54 memset(dp,0x3f,sizeof(dp));
55 dp[0]=0;
56 for(int sta=0;sta<=ti;sta++){
57 int num1=0; while((sta&(1<<num1))) num1++;
58 for(int i=num1+1;i<=pot;i++){
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 }
61 }
62 w(dp[ti]);
63 return 0;
64 }
65 }
66 signed main(){return WSN::main();}
总结一下这次打挂:
先打暴力,在没打暴力的时候想正解显然是非常弱智的行为(由杠哥大定理可得),
还有就是别被题目的无关题干骗了,觉得是啥就打啥。。。
Noip模拟10 2021.6.27的更多相关文章
- Noip模拟63 2021.9.27(考场惊现无限之环)
T1 电压机制 把题目转化为找那些边只被奇数环包含. 这样的话直接$dfs$生成一棵树,给每个点附上一个深度,根据其他的非树边都是返祖边 可以算出环内边的数量$dep[x]-dep[y]+1$,然后判 ...
- Noip模拟84 2021.10.27
以后估计都是用\(markdown\)来写了,可能风格会有变化 T1 宝藏 这两天老是会的题打不对,还是要细心... 考场上打的是维护\(set\)的做法,但是是最后才想出来的,没有维护对于是没有交. ...
- Noip模拟70 2021.10.6
T1 暴雨 放在第一道的神仙题,不同的做法,吊人有的都在用线段树维护$set$预处理 我是直接$dp$的,可能代码的复杂度比那种的稍微小一点 设$f[i][j][p][0/1]$表示考虑了前$i$列, ...
- Noip模拟76 2021.10.14
T1 洛希极限 上来一道大数据结构或者单调队列优化$dp$ 真就没分析出来正解复杂度 正解复杂度$O(q+nm)$,但是据说我的复杂度是假的 考虑一个点转移最优情况是从它上面的一个反$L$形转移过来 ...
- Noip模拟69 2021.10.5
考场拼命$yy$高精度结果没学好$for$循环痛失$50pts$,当场枯死 以后一定打对拍,要不考后会... T1 石子游戏 首先要知道典型的$NIM$博弈,就是说如果所有堆石子个数的异或和为$0$则 ...
- Noip模拟50 2021.9.10
已经好长时间没有考试不挂分的良好体验了... T1 第零题 开场数据结构,真爽 对于这道题首先要理解对于一条链从上向下和从下向上走复活次数相等 (这可能需要晚上躺在被窝里面脑摸几种情况的样例) 然后就 ...
- Noip模拟35 2021.8.10
考试题目变成四道了,貌似确实根本改不完... 不过给了两个小时颓废时间确实很爽(芜湖--) 但是前几天三道题改着不是很费劲的时候为什么不给放松时间, 非要在改不完题的时候颓?? 算了算了不碎碎念了.. ...
- Noip模拟81 2021.10.20
T1 语言 比较简单的题,然后就瞎写了,所以考场上就我一个写了线段树的,所以我的常数.... 所以就枚举动词的位置,找前面后面有没有出现$4$即可 1 #include<bits/stdc++. ...
- Noip模拟83 2021.10.26
T1 树上的数 有手就能在衡中$OJ$上过,但是$WaitingCoders$不行,就是这样 必须使用$O(n)$算法加上大力卡常,思路就是找子树内没更新的更新,更新过了直接$return$ 1 #i ...
随机推荐
- docker&flask快速构建服务接口(二)
系列其他内容 docker快速创建轻量级的可移植的容器✓ docker&flask快速构建服务接口✓ docker&uwsgi高性能WSGI服务器生产部署必备 docker&g ...
- C# Dapper基本三层架构使用 (三、BLL)
BLL层介绍 业务逻辑层用于做一些有效性验证的工作,以更好的保证程序运行的健壮性.如完成数据添加.修改和查询业务等:不允许指定的文本框中输入空字符串,数据格式是否正确以及数据类型验证:用户权限的合法性 ...
- nodejs安装 Later version of Node.js is already installed. Setup will now exit 及 node与npm版本不符
暴力删除nodejs导致无法重新安装 Later version of Node.js is already installed. Setup will now exit 1.电脑全局搜索nodej ...
- 【PHP数据结构】二叉树的遍历及逻辑操作
上篇文章我们讲了许多理论方面的知识,虽说很枯燥,但那些都是我们今天学习的前提,一会看代码的时候你就会发现这些理论知识是多么地重要了.首先,我们还是要说明一下,我们学习的主要内容是二叉树,因为二叉树是最 ...
- disruptor笔记之一:快速入门
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- 【Azure 应用服务】App Service For Linux 部署PHP Laravel 项目,如何修改首页路径为 wwwroot\public\index.php
问题描述 参考官方文档部署 PHP Laravel 项目到App Service for Linux环境中,但是访问应用时候遇见了500 Server Error 错误. 从部署的日志中,可以明确看出 ...
- Docker DevOps实战:GitLab+Jenkins(1)- GitLab容器搭建、使用SourceTree pull/push项目
GitLab容器搭建 # 创建GitLab容器# --restart always #重启,容器自动重启# --privileged=true #容器内使用root权限 [root@localhost ...
- 微信小程序 创建自己的第一个小程序
* 成为微信公众平台的开发者 注册 https://mp.weixin.qq.com * 登录 https://open.weixin.qq.com/ * 开发者工具下载 https://develo ...
- python+宝塔nginx+uwsgi的搭建方法
第一: 百度搜索宝塔,然后进入root,安装lnmp,根据情况选择选择需的选项进行安装,nginx必须安装. 第二: 进入宝塔,新建网站,网站的目录,先随便指定,绑定好的域名, 进入root,到宝塔网 ...
- 2021牛客暑期多校训练营9C-Cells【LGV引理,范德蒙德行列式】
正题 题目链接:https://ac.nowcoder.com/acm/contest/11260/C 题目大意 一个平面上,\(n\)个起点\((0,a_i)\)分别对应终点\((i,0)\),每次 ...