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. Identity角色管理二(显示角色)

    需要将目前所有角色名显示出来,方法同用户管理 一.创建Index acction public async Task<ActionResult> Index() { var roles = ...

  2. (xxl_job | quartz):XXL_JOB 对比 Quartz 一决高下!

    概述: XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速.学习简单.轻量级.易扩展. 现已开放源代码并接入多家公司线上产品线,开箱即用. 官方地址中文版:http://www.x ...

  3. RMQ区间最值查询

    RMQ区间最值查询 概述 RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A, 回答若干询问RMQ(A,i,j)(i,j<= ...

  4. PHP中一个好玩的性别判断扩展

    今天我们来学习的一个扩展同时它也是非常小众的一个扩展,其实说白了,或许是根本没什么人用过得扩展.当然,我们也只是出于学习的目的来看看这个扩展到底是什么东西,有什么好玩的地方. 扩展说明 Gender ...

  5. Roslyn(CSharpScript).Net脚本编译引擎使用过程内存增涨与稳定的方式

    目       录 1.      引用程序集... 1 2.      内存增涨的情况... 2 3.      内存稳定的情况... 4 1.   引用程序集 Roslyn 是微软公司开源的 .N ...

  6. 创建一个Orchard Core CMS 应用程序

    开始使用Orchard Core作为NuGet软件包 在本文中,我们将看到使用Orchard Core提供的NuGet包创建CMS Web应用程序是多么容易. 你可以在这里找到Chris Payne写 ...

  7. Orchard Core Framework Samples

    解决方案包含内容 多租户应用 一个ASP.NET Core MVC应用程序,它引用模块项目,并为两个启用了不同模块的租户提供支持. 此Web应用程序的主页提供了更多信息,并链接到两个租户和模块端点.租 ...

  8. AD学习笔记(基础)

    AD学习 1 学习思路 1.1 学什么 1.2 怎么学 2 AD本身 3 AD project 3.1 任务层级 3.2 PCB流程 4 原理图工作环境设置 5 开始 5.1工程创建 5.2 元件库介 ...

  9. english note [6.3to6.9]

    6.3 http://www.51voa.com/VOA_Special_English/pakistan-town-struggles-with-rise-in-hiv-infections-821 ...

  10. P4542-[ZJOI2011]营救皮卡丘【费用流,Floyd】

    正题 题目链接:https://www.luogu.com.cn/problem/P4542 题目大意 给出\(n+1\)个点\(m\)条边的无向图,\(k\)个人开始在\(0\)号点,一个人进入\( ...