博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
模拟赛12-10
阅读量:4875 次
发布时间:2019-06-11

本文共 3077 字,大约阅读时间需要 10 分钟。

感觉题目质量还是不错的

第一题。。

链接:

题意:

给出一个矩阵,求有多少个子矩阵元素和是p的倍数,p,a[i,j]<=1e6,n,m<=400;

题解:

首先看看暴力,确定矩形要o(n^4)的时候,计算要o(n^2),总的是o(n^6)

考虑二维前缀和优化计算,时间是o(n^4)的

似乎没有办法优化了

考虑一下这个问题的子问题

如果是一个一层的矩阵,也需要(n^2)的复杂度么

显然答案是否定的

区间[i,j]的和=sum[j]-sum[i-1],所以若要为k的倍数,即(sum[j]-sum[i-1])是k的倍数

该条件等价于(sum[j]) mod k和(sum[i-1]) mod k 相同

这样考虑到2维状态,我们可以先枚举出行,然后就变成了1维的问题

另外有些细节要注意

当枚举出行后,我们统计出sum[x] mod k的余数有哪些?有几个是这个余数?

可以用一个大数组a[1000000+10000]来记录

其次每次清除时只需要清除刚才修改过的地方,用memset会导致超时

代码:

****本来是用p写的,后来发现被卡常了

 

#include 
using namespace std;long long p[500][500],sum[500][500];long long f[1000010],pos[1000010],a[1000010],ans;int main(){ long long n,m,k; scanf("%lld%lld%lld",&n,&m,&k); for (long long i=1; i<=n; i++) for (long long j=1; j<=m;j++) scanf("%lld",&p[i][j]),sum[i][j]=(sum[i][j-1]+p[i][j])%k; for (long long i=1;i<=1000000; i++) f[i]=(i*(i-1))/2; for (long long i=1;i<=m;i++) for (long long j=i;j<=m;j++) { long long num=0; for (long long u=0; u<=n;u++) { long long x=(sum[u][j]-sum[u][i-1]+k)%k; num=(num+x+k)%k; pos[u]=num; a[num]++; } for (long long u=0;u<=n;u++) ans=ans+f[a[pos[u]]], a[pos[u]]=0; } printf("%lld",ans); return(0); }

 

分析:代码难度不大,思维还是有难度的

第二题:

链接:

题意:

给出一颗树,每个点可控制距离l以内的点,求最少需要几个点

题解:

看完题目,觉得不是树dp就是点分治了

后来想想好像做不了(当然k=1,2,3)拿部分分还是可以用树dp来做的

还是说正解吧,是看了题解才知道的

考虑对一个深度最深的节点,怎么样才能使得即能覆盖它又能对整颗树影响最大呢

很显然,深度越浅越好啊,如果它能覆盖当前节点,它一定能覆盖它的所有子树,

且对它的父亲以上及兄弟的节点相对于它的子树中的节点对他们的影响来说是最大的

那现在的大体思路就是:找到它的k代父亲,再用它去更新距离<=k的节点

另外思考一下 若x无k代父亲(即根节点到x的距离<k),那么我们应怎么办

其实这解决起来很简单的,因为x是深度最深的节点,所以这种情况下让根节点去覆盖就能覆盖所有节点了

另外对于维护当前深度最大值,可以刚开始弄出一个按dep排好序的数组

把头节点标记在1,之后每访问到一个点,将其f[i]值设为false

每次递增头结点直到找到为止,这个复杂度显然是o(n)的

复杂度分析:感觉有点难算,不能确定每个点会被访问几次,但画一画就能发现不会有太多节点被访问很多次

注意点:不要访问到f[i]=false就停止,举个例子x的某子孙之前覆盖了它,但没覆盖它3号儿子

现在它的另一个子孙,能覆盖它的3号儿子

代码:

 

#include
using namespace std;#define maxn 1000000struct re{
int a,b,c;};int n,m,l,c,d,head[maxn],fa[maxn];bool f[maxn],ff[maxn];re a[maxn],dep[maxn];void arr(int x,int y){ l++; a[l].a=head[x]; a[l].b=y; head[x]=l;};void dfs(int x,int y){ f[x]=false; dep[x].a=y; dep[x].b=x; int u=head[x]; while (u) { int v=a[u].b; if (f[v]) fa[v]=x,dfs(v,y+1); u=a[u].a; }};bool cmp(re x,re y){ return(x.a>y.a);};void dfs2(int x,int y,int z){ ff[x]=false; if (!y) return; int u=head[x]; while (u) { int v=a[u].b; if (v!=z) dfs2(v,y-1,x); u=a[u].a; }};int main(){ int tmp; cin>>n>>m>>tmp; for (int i=1;i
>c>>d,arr(c,d),arr(d,c); memset(f,true,sizeof(f)); memset(ff,true,sizeof(ff)); dfs(1,0); stable_sort(dep+1,dep+n+1,cmp); int h=1,ans=0; while (h<=n) { while (h<=n && !ff[dep[h].b]) h++; if (h<=n) { int x=dep[h].b,y=m; while (fa[x] && y>0) x=fa[x],y--; if (y>0) { ans++; goto tp; } dfs2(x,m,0),ans++; } } tp: cout<

 

转载于:https://www.cnblogs.com/yinwuxiao/p/8016847.html

你可能感兴趣的文章
平衡搜索树
查看>>
php工厂模式学习笔记
查看>>
MySQL表操作
查看>>
用PHP计算相对路径
查看>>
Windows Controls and WPF UserControls Inside an Xna Game Project
查看>>
整型表示
查看>>
OC基础9:预处理程序
查看>>
uva 11181 - Probability|Given
查看>>
【 D3.js 入门系列 --- 9.6 】 生产的包图
查看>>
request.getparameter和 request.getattribute的差别
查看>>
Bulk Insert命令具体
查看>>
Redhat Linux下的python版本号升级
查看>>
多功能检測按键-3 按键扫描 单按 长按 多个按键 响应方式
查看>>
mysql 用户管理 pymysql模块
查看>>
exit,_exit,wait,waitpid
查看>>
VUE2开发实战——搜索功能
查看>>
Codeforces997D Cycles in product 【FFT】【树形DP】
查看>>
基于Linux系统--web环境搭建
查看>>
gridview 根据条件更改链接的可用和颜色
查看>>
10.26会议记录
查看>>