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的更多相关文章

  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. 每日学习——iframe标签伪造ajax

    刚开始学习ajax,好难,看不懂啊看不懂. 伪造ajax加载网页 <!DOCTYPE html> <html> <head lang="en"> ...

  2. springboot多数据源配合docker部署mysql主从实现读写分离

    本篇主要有两部分: 1.使用docker部署mysql主从 实现主从复制 2.springboot项目多数据源配置,实现读写分离 一.使用docker部署mysql主从 实现主从复制 此次使用的是wi ...

  3. Shell系列(14)- declare声明变量

    declare声明变量类型 格式 declare [+/-] [选项] [变量名] 选项 -:给变量设定类型属性 +:取消变量的类型属性 -a :将变量声明为数组型 -i :将变量声明为整数型(int ...

  4. js模块化开发 AMD CMD Commonjs

    在es6全面实行开来之前  js实现模块开发方案有: 1.AMD 异步模块开发定义  依赖前置,requireJs应用了这一规范 require([module], callback); 加载完后回调 ...

  5. requests访问页面时set-cookie获取cookie

    import requests headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/ ...

  6. 在自己的项目中使用PCL

    在自己的项目中使用PCL项目设置:1.创建cpp文件,如pcd_write.cpp,文件内容如下例: #include <iostream>#include <pcl/io/pcd_ ...

  7. CF700E-Cool Slogans【SAM,线段树合并,dp】

    正题 题目链接:https://www.luogu.com.cn/problem/CF700E 题目大意 给出一个字符串\(S\),求一个最大的\(k\)使得存在\(k\)个字符串其中\(s_1\)是 ...

  8. 牛客练习赛79E-小G的数学难题【dp,单调队列】

    正题 题目链接:https://ac.nowcoder.com/acm/contest/11169/E 题目大意 给出\(n\)个三元组\((a_i,b_i,c_i)\). 要求选出一个集合\(S\) ...

  9. 使用jacob调用Windows的com对象,进行word、ppt等转换成ptf、html(二)

    富文本转pdf : 注意:simsun.ttc 可以百度下载:http://www.pc6.com/softview/SoftView_100415.html package com.orangecd ...

  10. 2017第二届广东省强网杯线上赛:WEB phone number (SQL注入)

    目录 解题思路 总结 解题思路 拿到题目的时候,只有一个登录界面 拿到登录界面,而且还伴随着有注册界面,联想到SQL的二次注入漏洞 尝试注册admin'#,并使用admin登录,发现登录失败,说明可能 ...