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

  1. NOIP模拟测试17&18

    NOIP模拟测试17&18 17-T1 给定一个序列,选取其中一个闭区间,使得其中每个元素可以在重新排列后成为一个等比数列的子序列,问区间最长是? 特判比值为1的情况,预处理比值2~1000的 ...

  2. 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) ...

  3. NOIP模拟测试17「入阵曲&#183;将军令&#183;星空」

    入阵曲 题解 应用了一种美妙移项思想, 我们先考虑在一维上的做法 维护前缀和$(sum[r]-sum[l-1])\%k==0$可以转化为 $sum[r]\% k==sum[l-1]\%k$开个桶维护一 ...

  4. 「题解」NOIP模拟测试题解乱写II(36)

    毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...

  5. 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组

    2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...

  6. 2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色

    2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 数据结构学傻的做法: 对每种颜色开动态开点线段树直接维 ...

  7. 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)

    2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...

  8. NOIP模拟测试1(2017081501)

    好,今天是cgg第一次举行模拟测试,希望各位支持. 时间限制:2小时 题目链接: 题目一:水得都没名字了 题目二:车站 题目三:选数 不要觉得2小时太少,我的题目很良心,都很简单. 答案可以在模拟测试 ...

  9. 「题解」NOIP模拟测试题解乱写I(29-31)

    NOIP模拟29(B) T1爬山 简单题,赛时找到了$O(1)$查询的规律于是切了. 从倍增LCA那里借鉴了一点东西:先将a.b抬到同一高度,然后再一起往上爬.所用的步数$×2$就是了. 抬升到同一高 ...

随机推荐

  1. 【leetcode】997. Find the Town Judge

    题目如下: In a town, there are N people labelled from 1 to N.  There is a rumor that one of these people ...

  2. nucleus plus学习总结(后续)

    前言:     刚刚抽筋点了保存发布,结果要审核,那就分开写个续好了. 内容: signal     信号是异步通知task的一种机制,HISR是不可以接收信号的,但是可以发送信号.     TCB中 ...

  3. doT模板引擎

    doT模板引擎是一个比较高效的引擎,一直都在使用,只有3kb大小,简洁的语法,无任何依赖,简单易用:下面的代码直接拷贝引用就可以使用: 插件代码 (function(){function p(b,a, ...

  4. Linux下github的使用

    在linux下搭建git环境 1.创建Github账号,https://github.com 2.Linux创建SSH密钥: ssh-keygen ##一直默认就可以了 3.将公钥加入到Github账 ...

  5. inline-block空隙怎么解决

    方法一:移除空格 元素间留白间距出现的原因就是标签段之间的空格,因此,去掉HTML中的空格,自然间距就木有了.考虑到代码可读性,显然连成一行的写法是不可取的,我们可以: <div class=& ...

  6. error C4996: 'stricmp': The POSIX name for this item is deprecated

    转自VC错误:http://www.vcerror.com/?p=164 问题描述: 最近使用了VS2012,在使用 stricmp和ltoa函数的时候,报出了以下错误信息 error C4996: ...

  7. 框架-.Net:.NET框架

    ylbtech-框架-.Net:.NET框架 .NET框架(.NET Framework) 是由微软开发,一个致力于敏捷软件开发(Agile softwaredevelopment).快速应用开发(R ...

  8. ng -v 不是内部或外部命令

    输入 npm install -g @angular/cli ng new my-app 提示ng -v 不是内部或外部命令 解决方法 1.安装过程中是否出错 原因可能是npm install -g  ...

  9. 自定义npm命令行工具,并发布到www.npmjs.com

    1.自定义一个npm脚本 - 1.新建一个项目(在任何路径都可以); - 2.使用`npm init -y`初始化项目 - 3.新建一个index.js文件,在文件的第一行添加 `#!/usr/bin ...

  10. 使用postman做接口测试----柠檬不萌!

    目录 一.GET和POST请求的区别 二.http协议 1.http请求分为两个部分 2.http状态码 三.使用postman测试HTTP接口 1.请求方式:get 2.请求方式:post 3.请求 ...