A.入阵曲

部分分很肥,正解写得常数稍大就会和暴力一个分,考试的时候写什么自己考虑。(滑稽

部分分的循环边界手抖写错了-25 (原本暴力分中的10分都没了啊啊啊)

没写挂的话应该有75,其实就是二维前缀和+暴力枚举点对统计+$a[i][j]$都相等时只枚举子矩形大小再乘上这种大小出现的次数。

正解:$(sum[r]-sum[l-1])\% K=0 \rightarrow sum[r]\% K=sum[l-1]\% K$

枚举行数$i,j$和列数$k$,维护i行和j行之间、k列左侧在%K意义下同余矩阵的个数,用桶来实现。

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=;
int n,m;
ll K,ans;
int a[N][N];
ll sum[N][N],sum1[N],cnt[];
int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-;ch=getchar();}
while(isdigit(ch))x=x*+ch-'',ch=getchar();
return x*f;
} int main()
{
n=read();m=read();K=1LL*read();
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
a[i][j]=read();
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
sum[i][j]=sum[i-][j]+sum[i][j-]-sum[i-][j-]+1LL*a[i][j];
for(int i=;i<n;i++)
for(int j=i+;j<=n;j++)
{
cnt[]=;
for(int k=;k<=m;k++)
{
sum1[k]=(sum[j][k]-sum[i][k]+K)%K;
ans+=cnt[sum1[k]];
cnt[sum1[k]]++;
}
for(int k=;k<=m;k++)cnt[sum1[k]]=;
}
cout<<ans<<endl;
return ;
}

B.将军令

我考场都能想到的sb贪心。每次取出深度最大且未被覆盖的点,在它的K级祖先上驻扎即可。前者用堆维护,后者直接暴力修改覆盖状态,注意向上修改时不要只遍历和它在一条链上的。

正确性?读者自证不难。(逃

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define pa pair<int,int>
#define re register
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-;ch=getchar();}
while(isdigit(ch))x=x*+ch-'',ch=getchar();
return x*f;
}
const int N=;
int n,K,t;
int to[N<<],nxt[N<<],head[N],tot;
inline void add(int x,int y)
{
to[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
int dep[N],fa[N];
priority_queue<pa> q;
void dfs1(int x,int deep)
{
dep[x]=deep;
for(re int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(!dep[y])dfs1(y,deep+),fa[y]=x;
}
return ;
}
int cover[N],anc,ans;
void getan(int x,int rest)
{
if(!rest||x==)
{
anc=x;
return ;
}
getan(fa[x],rest-);
return ;
}
void dfs2(int x,int rest,int f)
{
cover[x]=;
if(!rest)return ;
for(re int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(y==f)continue;
dfs2(y,rest-,x);
}
return ;
} int main()
{
n=read();K=read();t=read();
for(re int i=;i<n;i++)
{
int x=read(),y=read();
add(x,y);add(y,x);
}
dfs1(,);
for(re int i=;i<=n;i++)
q.push(make_pair(dep[i],i));
while(!q.empty())
{
int x=q.top().second;
q.pop();
if(cover[x])continue;
getan(x,K);
//cout<<anc<<endl;
dfs2(anc,K,-);
ans++;
}
cout<<ans<<endl;
return ;
}

C.星空

区间状态反转可以看作区间异或1,但区间操作不好处理,考虑通过差分转化为单点操作。即把对原数组上$[L,R]$区间的操作转化为差分数组上$L-1$和$R$两个点的操作。这里用到了异或差分:$dif[i]=a[i]\ xor\ a[i+1]$

所以问题变成了:有一个01串,每次对其中两个点$xor\ 1$,需要多少次把这个串的每一位都变成0。(差分数组全0对应原数组全1)

可以发现,消去两个1的费用与他们之间的距离有关。bfs预处理出来后,问题再次得到转化:每次取出一对物品,每对物品取出都有一定代价,如何取出使得代价最小。由于不亮的灯泡很少,这个问题完全可以状压解决。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-;ch=getchar();}
while(isdigit(ch))x=x*+ch-'',ch=getchar();
return x*f;
}
const int N=;
int n,m,K;
int a[N],op[N],dif[N];
int pos[N],sz;
int vis[N],dis[][],d[N];
int find0[N<<],dp[N<<];
void bfs(int node)
{
memset(d,,sizeof(d));
memset(vis,,sizeof(vis));
queue<int> q;
q.push(node);
vis[node]=;d[node]=;
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=;i<=m;i++)
{
int s1=x+op[i],s2=x-op[i];
if(s1<=n&&!vis[s1])
{
q.push(s1);
d[s1]=d[x]+;
vis[s1]=;
}
if(s2>=&&!vis[s2])
{
q.push(s2);
d[s2]=d[x]+;
vis[s2]=;
}
}
}
} int main()
{
n=read();K=read();m=read();
for(int i=;i<=K;i++)
a[read()]=;
for(int i=;i<=m;i++)
op[i]=read();
for(int i=;i<=n;i++)
{
dif[i]=a[i]^a[i+];
if(dif[i])pos[++sz]=i;
}
for(int i=;i<=sz;i++)
{
bfs(pos[i]);
for(int j=;j<=sz;j++)
dis[i][j]=d[pos[j]];
}
for(int s=;s<(<<sz);s++)
{
find0[s]=sz-;
for(int i=;i<sz;i++)
if(((s>>i)&)==)
{
find0[s]=i;
break;
}
}
memset(dp,0x3f,sizeof(dp));
dp[]=;
for(int s=;s<(<<sz);s++)
for(int i=find0[s]+;i<sz;i++)
{
if(((s>>i)&)==&&dis[find0[s]+][i+])
{
int now=(s|(<<find0[s])|(<<i));
dp[now]=min(dp[now],dp[s]+dis[find0[s]+][i+]);
//cout<<dp[now]<<endl;
}
}
cout<<dp[(<<sz)-]<<endl;
return ;
}

[NOIP]模拟17 题解的更多相关文章

  1. NOIP模拟17.9.21

    NOIP模拟17.9.21 3 58 145 201 161.5 样例输出21.6 数据规模及约定对于40% 的数据,N <= 20对于60% 的数据,N <= 1000对于100% 的数 ...

  2. NOIP模拟17.9.22

    NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥

  3. NOIP模拟 17.8.20

    NOIP模拟17.8.20 A.阶乘[题目描述]亲爱的xyx同学正在研究数学与阶乘的关系,但是他喜欢颓废,于是他就制作了一个和阶乘有关系的数学游戏:给出两个整数 n,m,令 t = !n,每轮游戏的流 ...

  4. NOIP模拟 17.8.18

    NOIP模拟17.8.18 A.小菜一碟的背包[题目描述]Blice和阿强巴是好朋友但萌萌哒Blice不擅长数学,所以阿强巴给了她一些奶牛做练习阿强巴有 n头奶牛,每头奶牛每天可以产一定量的奶,同时也 ...

  5. NOIP模拟 17.8.15

    NOIP模拟17.8.15 A 债务文件名 输入文件 输出文件 时间限制 空间限制debt.pas/c/cpp debt.in debt.out 1s 128MB[题目描述]小 G 有一群好朋友,他们 ...

  6. NOIP模拟 17.8.17

    NOIP模拟17.8.17 A 小 G 的字符串文件名 输入文件 输出文件 时间限制 空间限制str.pas/c/cpp str.in str.out 1s 128MB[题目描述]有一天,小 L 给小 ...

  7. NOIP模拟 17.8.16

    NOIP模拟17.8.16 A 债务文件名 输入文件 输出文件 时间限制 空间限制debt.pas/c/cpp debt.in debt.out 1s 128MB[题目描述]小 G 有一群好朋友,他们 ...

  8. NOIP模拟 17.8.14

    NOIP模拟17.8.14 (天宇哥哥考察细心程度的题) [样例解释]如果删去第一个 1:在[3,1,2]中有 3 个不同的数如果删去 3:在[1,1,2]中有 2 个不同的数如果删去第二个 1:在[ ...

  9. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

随机推荐

  1. 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数

    目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...

  2. windows shell命令和快捷键

    // 这下面的宏,貌似都能通过shell:调用 // SHGetSpecialFolderLocation // // Caller should use SHGetMalloc to obtain ...

  3. MySQL 存储过程-definer和invoker的解释

    [definer和invoker的解释] 创建存储过程的时候可以指定 SQL SECURITY属性,设置为 DEFINER 或者INVOKER,用来奉告mysql在执行存储过程的时候,,是以DEFIN ...

  4. 监听器、拦截器完成对session、cookie的会话控制

    package com.trsmedia.interceptor; import java.util.Date; import java.util.Timer; import java.util.Ti ...

  5. The document cannot be opened. It has been renamed, deleted or moved.

    In the Individual components section of the Visual Studio Installer, make sure that Razor Language S ...

  6. Area--->AreaRegister.RegisterAllArea()与Area区域的解析

    文章引导 MVC路由解析---IgnoreRoute MVC路由解析---MapRoute MVC路由解析---UrlRoutingModule Area的使用 Area--->AreaRegi ...

  7. 2019牛客多校第五场B-generator 1(矩阵快速幂)

    generator 1 题目传送门 解题思路 矩阵快速幂.只是平时的矩阵快速幂是二进制的,这题要用十进制的快速幂. 代码如下 #include <bits/stdc++.h> #defin ...

  8. Scrapy框架: 第一个程序

    首先创建项目: scrappy start project maitian 第二步: 明确要抓取的字段items.py import scrapy class MaitianItem(scrapy.I ...

  9. ansible了解

    基础知识: ansible简介 ansible 是个什么东西呢?基于 Python paramiko 开发,分布式,无需客户端,轻量级,配置语法使用 YMAL 及 Jinja2模板语言,更强的远程命令 ...

  10. 【python标准库学习】thread,threading(一)多线程的介绍和使用

    在单个程序中我们经常用多线程来处理不同的工作,尤其是有的工作需要等,那么我们会新建一个线程去等然后执行某些操作,当做完事后线程退出被回收.当一个程序运行时,就会有一个进程被系统所创建,同时也会有一个线 ...