NOIP模拟测试17
T1:入阵曲
题目大意:给定一个N*M的矩形,问一共有多少个子矩形,使得矩形内所有书的和为k的倍数。
60%:N,M<=80
枚举矩形的左上角和右下角,用二维前缀和求出数字之和。
时间复杂度$O(N^4)$
100%
我们发现美剧每个矩形的复杂度已经为N4,那么我们改为枚举矩形的边界。先枚举左右边界,再从上到下枚举下边界,两个矩形相减便可得出所有矩形,枚举时将每个矩形的区间和压入桶中,每次枚举时直接在桶中查询,左右边界更换时清桶。注意下边界要从0开始枚举。
时间复杂度$O(N^3)$
记得要卡常。
Code:
#include<iostream>
#include<cstdio>
const int L=<<|;
char buffer[L],*S,*T;
#define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++)
#define LL unsigned long long
#define rint register unsigned int
using namespace std;
const unsigned int N=;
int n,m,d;
int s[N][N];
unsigned int dfn[],t[];
inline int read()
{
rint s=;char c=getchar();
while(c<||c>) c=getchar();
while(c>=&&c<=)s=(s<<)+(s<<)+(c^),c=getchar();
return s;
}
int main()
{
n=read();m=read();d=read();
for(rint i=;i<=n;++i){
for(rint j=;j<=m;++j)
s[i][j]=(s[i-][j]+s[i][j-]-s[i-][j-]+read())%d;
}
LL ans=;rint df=;
for(rint i=;i<=m;++i){
for(rint j=i;j<=m;++j){
dfn[]=++df;t[]=;
for(rint k=;k<=n;++k){
register int now=((s[k][j]-s[k][j-i])%d+d)%d;
if(dfn[now]!=df){
dfn[now]=df;t[now]=;
}
else{
ans+=t[now];++t[now];
}
}
}
}
printf("%lld\n",ans);
return ;
}
T1
T2:将军令:
题目大意:给定一棵树,和一个距离K,在某个节点驻扎军队可以占领所有与该节点距离不超过K的点,求最少要驻扎多少军队。
此题和小胖守皇宫类似,不过权值均为一,可以用贪心做。
将所有的点按深度排序,从前往后扫,遇到未标记的点,则从他的K辈祖先处开始进行dfs,暴力标记,将ans加一,扫到最后的结果即是答案。
贪心策略证明:
由于每次找的是深度最大的点,那么每次dfs一定能标记到当前子树的所有儿子,同时要想使其他子树需要的军队尽可能少,则应再次条件下尽可能向上,越向上越能标记更多的点。证明完毕,贪心策略正确。
时间复杂度$O(NK)$
Code:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=;
int n,k,t,m=,ans=;
int fi[N],d[N],f[N];
bool v[N];
struct edge{
int v,ne;
}e[N<<];
struct point{
int d,id;
}p[N];
void add(int x,int y)
{
e[++m].v=y;
e[m].ne=fi[x];fi[x]=m;
}
bool comp(const point a1,const point a2)
{
return a1.d>a2.d;
}
int read()
{
int s=;char c=getchar();
while(c<''||c>'') c=getchar();
while(c>=''&&c<=''){
s=(s<<)+(s<<)+c-'';
c=getchar();
}
return s;
}
void dfs(int x,int pa)
{
p[x].id=x;
for(int i=fi[x];i!=;i=e[i].ne){
int y=e[i].v;
if(y==pa) continue;
f[y]=x;
p[y].d=p[x].d+;
dfs(y,x);
}
}
void work(int x,int pa,int d)
{
v[x]=true;
if(d==) return;
for(int i=fi[x];i!=;i=e[i].ne){
int y=e[i].v;
if(y==pa) continue;
work(y,x,d-);
}
}
int main()
{
n=read();k=read();t=read();
for(int i=;i<n;i++){
int x=read(),y=read();
add(x,y);add(y,x);
}
p[].d=;dfs(,);
sort(p+,p+n+,comp);
for(int i=;i<=n;i++){
int x=p[i].id;
if(!v[x]){
for(int i=;i<=k&&f[x]!=;i++)
x=f[x];
work(x,,k);ans++;
}
}
printf("%d\n",ans);
return ;
}
T2
T3:星空
题目大意:给一个0/1串,每次能将一个给定长度的区间去反,求最少要几次将整个串变为零。
0/1串长度:N<=40000,区间长度数:M<=64,1的个数:K<=8
24%做法:N<=16
直接状压,跑BFS即可。DFS会T飞
复杂度$O(N*2^N)$
100%做法:
我们发现相对于N,K很小,可以用来做做文章。
开始转化题意:
我们设灯亮为0,灯灭为1,则序列全为0时,所有灯都点亮。
不难发现当N很大时,该序列中仅有K个1,我们从0位开始将每一位与其后一位亦或,则最多有2K个数与前一位不同,最多有2K个1,每次选择一段区间[L,R]取反,仅会改变第L-1位和第R位的值,相当于将序列中一定距离的点同时取反。
题意转化为:给一个0/1串,每次选择相距给定长度的点同时取反,最少几次能将整个串全变为0。
若选择的两个书均为0,没有任何意义;
若选择的两个数均为1,则相互抵消;
若其中一个数为0,另一个数为1,相当与将1移动一定距离。
题意再次转化为:数轴上有最多2K个点,每次将一个点移动一段距离,两个点碰在一起后同时消失,最少几次能让所有点消失。
此时K的范围状压可以接受,BFS算出两点间移动的最少次数,用状压DP简单解决。
时间复杂度$O(MNK+K*2^K)$或$O(MNK+K^2*2^K)$
Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=;
const int inf=;
int n,k,m,tot=;
int a[N],b[N],v[N],c[],d[][],e[];
int dp[<<];
queue<int> q;
int read()
{
int s=;char c=getchar();
while(c<''||c>'') c=getchar();
while(c>=''&&c<=''){
s=(s<<)+(s<<)+c-'';
c=getchar();
}
return s;
}
void bfs(int pos)
{
int now=c[pos];
memset(v,,sizeof(v));
v[now]=;q.push(now);
while(!q.empty()){
int x=q.front();q.pop();
for(int i=;i<=m;i++){
int y=x+e[i];
if(y<=n+&&v[y]==){
v[y]=v[x]+;q.push(y);
}
y=x-e[i];
if(y>=&&v[y]==){
v[y]=v[x]+;q.push(y);
}
}
}
for(int i=;i<=tot;i++){
if(i!=pos){
if(v[c[i]]==) d[pos][i]=inf;
else d[pos][i]=v[c[i]]-;
}
}
}
int main()
{
n=read();k=read();m=read();
for(int i=;i<=k;i++){
int x=read();
a[x]=;
}
for(int i=;i<=n;i++){
b[i]=a[i]^a[i+];
if(b[i]==) c[++tot]=i+;
}
for(int i=;i<=m;i++)
e[i]=read();
for(int i=;i<=tot;i++)
bfs(i);
for(int i=;i<(<<tot);i++)
dp[i]=inf;
for(int i=;i<(<<tot);i++){
for(int j=;j<=tot;j++){
if(((i>>(j-))&)==) continue;
for(int g=;g<=tot;g++){
if(g==j) continue;
if(((i>>(g-))&)==) continue;
dp[i|(<<(j-))|(<<(g-))]=min(dp[i|(<<(j-))|(<<(g-))],dp[i]+d[j][g]);
}
}
}
printf("%d\n",dp[(<<tot)-]);
return ;
}
T3
NOIP模拟测试17的更多相关文章
- NOIP模拟测试17&18
NOIP模拟测试17&18 17-T1 给定一个序列,选取其中一个闭区间,使得其中每个元素可以在重新排列后成为一个等比数列的子序列,问区间最长是? 特判比值为1的情况,预处理比值2~1000的 ...
- 8.11 NOIP模拟测试17 入阵曲+将军令+星空
T1 入阵曲 前缀和维护可以得60分 f[x1][y1][x2][y2]=sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1]; O(n4) ...
- NOIP模拟测试17「入阵曲·将军令·星空」
入阵曲 题解 应用了一种美妙移项思想, 我们先考虑在一维上的做法 维护前缀和$(sum[r]-sum[l-1])\%k==0$可以转化为 $sum[r]\% k==sum[l-1]\%k$开个桶维护一 ...
- 「题解」NOIP模拟测试题解乱写II(36)
毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组
2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色
2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 数据结构学傻的做法: 对每种颜色开动态开点线段树直接维 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)
2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...
- NOIP模拟测试1(2017081501)
好,今天是cgg第一次举行模拟测试,希望各位支持. 时间限制:2小时 题目链接: 题目一:水得都没名字了 题目二:车站 题目三:选数 不要觉得2小时太少,我的题目很良心,都很简单. 答案可以在模拟测试 ...
- 「题解」NOIP模拟测试题解乱写I(29-31)
NOIP模拟29(B) T1爬山 简单题,赛时找到了$O(1)$查询的规律于是切了. 从倍增LCA那里借鉴了一点东西:先将a.b抬到同一高度,然后再一起往上爬.所用的步数$×2$就是了. 抬升到同一高 ...
随机推荐
- linux(一)vi和vim
vi 多模式文本编辑器 多模式产生的原因 四种模式 正常模式 插入模式 命令模式 可视模式 vi man vi vim vim正常模式 直接vim回车,或vim空格文件名回车 i进入插入模式 I(sh ...
- ruby puts语法
str = "Welcom to china" str1 = str puts str + " 1" puts str1 + " 1" de ...
- bzoj 2435
http://www.lydsy.com/JudgeOnline/problem.php?id=2435 noi 你为什么那么diao, 这种世纪水题刷一道少一道啊... 我原来还以为是两边的联通块大 ...
- chroot()使用
好多的程序,都有使用chroot来是程序chroot到一个目录下面,来保护文件系统,今天在看snort代码的时候,看到了实现,就贴出一个测试程序来,实际上是比较简单的. chroot()在lin ...
- ShellListView
過濾ShellListView顯示的檔案 有關這方面的元件你可以在Win3.中找到相關元件 你可以使用四個元件搭配應該就可以你所需要的功能 DriveComboBox1.FilterComboBox1 ...
- taomcat中catalina.out文件
项目中发现在linux环境下布署的tomcat所占用的磁盘空间越来越大,是catalina.out 文件,每天几乎是2个G,发现可能会影响到tomcat服务(没确定)正常访问.文件这么大,其实已经无法 ...
- 聊一聊 http2.0
1. 我们认识http 协议,从最初的,客户端与服务器进行通讯,基于连接发生的请求与响应 在HTTP1.0时代,连接无法复用,每次下完单,都被强制登出/关机,下一次下单,就得重新登录. 为了解决htt ...
- ListView 分页显示(转载+修改)下
通过实践发现,尚大大在判断”上一页“按钮和”下一页按钮“是否可用的地方,有问题: 原代码: public void checkButton(){ //索引值小于等于0,表示不能向前翻页了,以经到了第一 ...
- python自动化之函数封装
函数最重要的目的是方便我们重复使用相同的一段程序. 将一些操作隶属于一个函数,以后你想实现相同的操作的时候,只用调用函数名就可以,而不需要重复敲所有的语句. 前面一些记录了selenium的各种API ...
- LInux终端中Ctrl+S卡死
因为初学Linux,在vim中写东西是总是喜欢按Ctrl+s来保存内容导致终端突然卡主,然后上网查资料发现了Ctrl+s 暂停屏幕输出[锁住终端]而对应的按键是Ctrl+q 恢复屏幕输出[解锁终端]