链接:https://www.nowcoder.com/acm/contest/131/B
来源:牛客网

矩阵 M 包含 R 行 C 列,第 i 行第 j 列的值为 Mi,j
请寻找一个子矩阵,使得这个子矩阵的和最大,且满足以下三个条件:
子矩阵的行数不能超过 X 行。
子矩阵的列数不能超过 Y 列。
子矩阵中 0 的个数不能超过 Z 个。
请输出满足以上条件的最大子矩阵和。

输入描述:

第一行输入五个整数 R,C,X,Y,Z。
接下来 N 行,每行输入 M 个整数,第 i 行第 j 列的整数表示 Mi,j
1 ≤ R,C ≤ 500.
1 ≤ X ≤ R.
1 ≤ Y ≤ C.
1 ≤ Z ≤ R x C. |Mij|<=1e9

输出描述:

输出满足以上条件的最大子矩阵和。

考虑枚举行数。
枚举行数后枚举从哪行开始。
预处理出来纵向前缀和,然后枚举的时候就把每一个元素转化成柱形图那样的格式,然后求最大值就好了。 求最大值时的思想是枚举最后一个元素,然后看前面的元素,前面元素大于0直接放,小于0的就把队尾取出来,加到这个元素,直到不小于0或者队列为空位置。
以数结尾的最大值是目前队列元素里面的和。 用单调栈也可以做。
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int N=;
int q[N],p[N],zt[N][N],L[N];
long long mp[N][N],up[N][N],a[N];
int R,C,X,Y,Z;
long long work(){
for(int i=;i<=C;++i) p[i]=i;
int h=,r=;
long long ans=,sum=;
q[]=;
for(int i=;i<=C;++i)
{
while(h<=r&&p[q[h]]<=i-Y) sum-=a[q[h++]];
while(h<=r&&a[i]<) {
sum-=a[q[r]];
a[i]+=a[q[r]];
p[i]=p[q[r--]];
}
if(a[i]>) sum+=a[i],q[++r]=i;
while(h<=r&&(L[i]-L[p[q[h]]]>Z)) sum-=a[q[h++]];
ans=max(ans,sum);
}
return ans;
}
int main(){
long long ans=;
scanf("%d%d%d%d%d",&R,&C,&X,&Y,&Z);
for(int i=;i<=R;++i) for(int j=;j<=C;++j) scanf("%lld",&mp[i][j]);
for(int i=;i<=R;++i) for(int j=;j<=C;++j) up[i][j]=up[i-][j]+mp[i][j],zt[i][j]=zt[i-][j]+(mp[i][j]==);
for(int len=;len<=X;++len){
for(int i=;i<=R-len+;++i){
for(int j=;j<=C;++j) a[j]=up[i+len-][j]-up[i-][j],L[j]=zt[i+len-][j]-zt[i-][j];
for(int j=;j<=C;++j) L[j]+=L[j-];
ans=max(ans,work());
}
}
printf("%lld\n",ans);
}

链接:https://www.nowcoder.com/acm/contest/131/C
来源:牛客网

题目描述

有一棵树包含 N 个节点,节点编号从 1 到 N。节点总共有 K 种颜色,颜色编号从 1 到 K。第 i 个节点的颜色为 Ai
Fi 表示恰好包含 i 种颜色的路径数量。请计算:

输入描述:

第一行输入两个正整数 N 和 K,N 表示节点个数,K 表示颜色种类数量。
第二行输入 N 个正整数,A

i

表示第 i 个节点的颜色。
接下来 N - 1 行,第 i 行输入两个正整数 Ui 和 Vi,表示节点 Ui 和节点 Vi 之间存在一条无向边,数据保证这 N-1 条边连通了 N 个节点。
1 ≤ N ≤ 50000.
1 ≤ K ≤ 10.
1 ≤ Ai ≤ K.

输出描述:

输出一个整数表示答案。

题解:T[i]表示集合意义上小于等于i的路径的总数,状态总数(i的范围)为2^k。
求T[i]只要把i集合中的点拿出来做联通块,每个联通块的价值就是联通块中点的数目+C (点的数目,2)
然后求每个状态的点的数量,只需要让他减去他的所有真子集即可。
然后转态再转为数量就可以了。
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=5e4+;
const int P=1e9+;
vector<pair<int,int> >G;
int f[N],sz[N],n,k,a[N];
int T[],tran[],F[];
int findx(int x){
return (x==f[x])?x:(f[x]=findx(f[x]));
}
int main(){
scanf("%d%d",&n,&k);
for(int i=;i<=n;++i) scanf("%d",a+i),--a[i];
for(int i=;i<n;++i) {
int x,y;
scanf("%d%d",&x,&y);
G.push_back(make_pair(x,y));
}
for(int i=;i<;++i) {
int x,y,fx,fy;
for(int j=;j<=n;++j) f[j]=j,sz[j]=;
for(int j=;j<n-;++j) {
x=G[j].first,y=G[j].second;
if(((<<a[x])&i)&&((<<a[y])&i)) {
fx=findx(x),fy=findx(y);
sz[fx]+=sz[fy];
f[fy]=fx;
}
}
for(int j=;j<=n;++j) if(((<<a[j])&i)&&(f[j]==j)){
T[i]=(T[i]+sz[j]+(1LL*sz[j]*(sz[j]-)/)%P)%P;
}
}
for(int i=;i<;++i) for(int j=;j<i;++j)
if(!((i^j)&j))
{
T[i]=(T[i]-T[j]+P)%P;
}
for(int i=;i<;++i) for(int j=;j<;++j)
if(i&(<<j)) ++tran[i];
for(int i=;i<;++i) F[tran[i]]=(F[tran[i]]+T[i])%P;
int x=,ans=;
for(int i=;i<=k;++i){
ans=(ans+1LL*F[i]*x%P)%P;
x=131LL*x%P;
}
printf("%d\n",ans);
}

链接:https://www.nowcoder.com/acm/contest/131/F
来源:牛客网

ZZT 得到了一个字符串 S 以及一个整数 K。
WZH 在 1995 年提出了“优雅 K 串”的定义:这个字符串每一种字符的个数都是 K 的倍数。
现在 ZZT 想要对字符串进行 Q 次询问,第 i 次询问给出一个区间 [Li, Ri],他想计算 [Li, Ri] 中有多少个子串是“优雅 K 串”。
由于 ZZT 忙于工作,所以他把这个问题交给了你,请你帮忙解决。

输入描述:

第一行输入一个正整数 K。
第二行输入一个字符串 S。
第三行输入一个正整数 Q,表示有 Q 次询问。
接下来 Q 行,每行输入两个正整数 Li 和 Ri,表示第 i 次询问。
1 ≤ K ≤ 50.
1≤ | S | ≤ 3 x 104 且 S 仅包含小写英文字母.
1≤ Q ≤ 3 x 104.
1 ≤ Xi ≤ Yi ≤ N.

输出描述:

每次询问,输出一个正整数,表示满足条件的“优雅 K 串”的数量。

输入

复制

1
abc
3
1 3
1 2
2 3

输出

复制

6
3
3 题解:先求前缀和,然后可知前缀和相同的左开右闭区间就是所求区间(在模k意义下),所以每个询问的l要先减掉1。
然后前缀和转哈希,对每一个点赋予哈希后的权值。
然后就莫队就好了。
也可以用字典树写。
#include<map>
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=3e4+;
int now,Be[N],ans[N];
int pp[N][];
unsigned long long a[N]; struct Query{
int l,r,id;
bool operator < (const Query &A)const{
return Be[l]==Be[A.l]?r<A.r:l<A.l;
}
}q[N];
char s[N];
int k,l,r;
map<unsigned long long,int> M;
void work(int x,int y){
if(y==) now+=M[a[x]]++;
else now-=--M[a[x]];
}
int main(){
int m,len,unit;
now=;
scanf("%d %s",&k,s+);
len=strlen(s+);
//M[0]=1;
for(int i=;s[i];++i) {
for(int j=;j<;++j) pp[i][j]=pp[i-][j];
pp[i][s[i]-'a']=(pp[i][s[i]-'a']+)%k;
}
for(int i=;s[i];++i) {
unsigned long long pt=;
for(int j=;j<;++j) pt=pt*+pp[i][j];
a[i]=pt;
}
unit=sqrt(len);
for(int i=;i<=len;++i) Be[i]=i/unit+;
scanf("%d",&m);
for(int i=;i<=m;++i) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i,--q[i].l;
sort(q+,q+m+);
l=q[].l,r=q[].l-;
for(int i=;i<=m;++i) {
while(l<q[i].l) work(l++,-);
while(l>q[i].l) work(--l,);
while(r<q[i].r) work(++r,);
while(r>q[i].r) work(r--,-);
ans[q[i].id]=now;
}
for(int i=;i<=m;++i) {
printf("%d\n",ans[i]);
}
}


牛客网挑战赛19 B,C,F的更多相关文章

  1. 牛客~~wannafly挑战赛19~A 队列

    链接:https://www.nowcoder.com/acm/contest/131/A来源:牛客网 题目描述 ZZT 创造了一个队列 Q.这个队列包含了 N 个元素,队列中的第 i 个元素用 Qi ...

  2. 牛客网挑战赛24 青蛙(BFS)

    链接:https://www.nowcoder.com/acm/contest/157/E来源:牛客网 有一只可爱的老青蛙,在路的另一端发现了一个黑的东西,想过去一探究竟.于是便开始踏上了旅途 一直这 ...

  3. 题解——牛客网Wannafly挑战赛23 B-游戏 (SG函数)

    前言 比赛的时候没学过SG函数的蒟蒻以为是道结论题,但是不是QwQ 和dummyummy巨佬一起推了快三个小时的规律 最后去问了真正的巨佬__stdcall __stdcall面带微笑的告诉我们,这是 ...

  4. 牛客网 牛客小白月赛1 F.三视图

    F.三视图   链接:https://www.nowcoder.com/acm/contest/85/F来源:牛客网     这个题自己想一下三维的,正视图和左视图中y轴为行数,x轴和z轴是列数,因为 ...

  5. 牛客网练习赛23 F 托米的游戏

    链接:https://www.nowcoder.com/acm/contest/156/F 来源:牛客网 题目描述 题目背景编不下去了 托米有一棵有根树 T, 树根为1,每轮他会在剩下的子树中等概率一 ...

  6. 牛客网——F小牛再战(博弈,不懂)

    链接:https://www.nowcoder.net/acm/contest/75/F来源:牛客网 题目描述 共有N堆石子,已知每堆中石子的数量,两个人轮流取石子,每次只能选择N堆石子中的一堆取一定 ...

  7. 牛客网——F求最大值

    链接:https://www.nowcoder.net/acm/contest/29/F来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K ...

  8. 牛客网 牛客练习赛43 F.Tachibana Kanade Loves Game-容斥(二进制枚举)+读入挂

    链接:https://ac.nowcoder.com/acm/contest/548/F来源:牛客网 Tachibana Kanade Loves Game 时间限制:C/C++ 1秒,其他语言2秒 ...

  9. 牛客网暑期ACM多校训练营(第五场):F - take

    链接:牛客网暑期ACM多校训练营(第五场):F - take 题意: Kanade有n个盒子,第i个盒子有p [i]概率有一个d [i]大小的钻石. 起初,Kanade有一颗0号钻石.她将从第1到第n ...

随机推荐

  1. 理解分布式一致性:Paxos协议之Generalized Paxos & Byzantine Paxos

    理解分布式一致性:Paxos协议之Generalized Paxos & Byzantine Paxos Generalized Paxos Byzantine Paxos Byzantine ...

  2. java 之 继承 super关键籽 this关键字 final关键字

    继承 语法: 使用 extends 来继承 class子类    extends父类{ 子类属性 子类方法 } 继承的特点: 1.子类会把父类所有的属性和方法继承下来,final修饰的类是不可以被继承 ...

  3. webpack插件解析:HtmlWebpackPlugin是干什么的以及如何使用它

    HtmlWebpackPlugin是一个出现频率比较高的webpack插件,本文对其作用和配置作一番比较详细的分析(本文的配置均在webpack.config.js中进行). 为何使用它 简单来说,H ...

  4. python(面向对象-类封装调用)

    一.面对对象思想 (1)大家肯定听过 Python 中”一切皆对象“的说法,但可能并不了解它的具体含义,只是在学习的时候听说 Python 是面向对象的编程语言,本节将向大家详细介绍 Python 面 ...

  5. Fiddler 介绍

    1.fiddler原理介绍 fiddler 是一个抓包工具,当浏览器访问服务器会形成一个请求,此时,fiddler就处于请求之间,当浏览器发送请求,会先经过 fiddler,然后在到服务器:当服务器有 ...

  6. 洛谷P5018 对称二叉树

    不多扯题目 直接题解= = 1.递归 由题目可以得知,子树既可以是根节点和叶节点组成,也可以是一个节点,题意中的对称二叉子树是必须由一个根节点一直到树的最底部所组成的树. 这样一来就简单了,我们很容易 ...

  7. Educational Codeforces Round 77 (Rated for Div. 2) C. Infinite Fence

    C. Infinite Fence 题目大意:给板子涂色,首先板子是顺序的,然后可以涂两种颜色,如果是r的倍数涂成红色,是b的倍数涂成蓝色, 连续的k个相同的颜色则不能完成任务,能完成任务则输出OBE ...

  8. K - Leapin' Lizards HDU - 2732 网络流

    题目链接:https://vjudge.net/contest/299467#problem/K 这个题目从数据范围来看可以发现是网络流,怎么建图呢?这个其实不是特别难,主要是读题难. 这个建图就是把 ...

  9. 整型和浮点型与QByteArray的转换

    目录 QByteArray 整型 QByteArray 浮点型 QByteArray QByteArray The QByteArray class provides an array of byte ...

  10. 【MySQL基础总结】常用函数库

    常用函数库 数学函数 分类及含义 示例 字符串函数 分类及含义 示例 日期时间函数 分类及含义 示例 条件判断函数 分类及含义 示例 系统函数 分类及含义 加密函数 分类及定义 其他常用函数 分类及含 ...