CodeForces:372(div1)div373(div2)

前言

中规中矩的比赛 想不出形容词了
373AB是水题
372ABD都是小清新且码量较小的好题
372C之前做过了
372E毒瘤几何+组合数学,没有洛谷题解,CF题解完全看不懂,直接弃疗qwq

CF373A Collecting Beats is Fun

Description\text{Description}Description

一共有 4×4=164\times4=164×4=16 个格子,每个格子 (i,j)(i,j)(i,j) 需要在 ti,jt_{i,j}ti,j 时刻点击(若为星号则不需要点击),你每只手同一时刻只能点击 kkk 个格子(注意你有两只手!),求你是否能完成任务。
ti,jt_{i,j}ti,j 是一个 1−91-919 的数字。

Solution\text{Solution}Solution

水题。
4×44\times44×4 扫一遍,开一个桶记录每个时刻需要点多少个格子,最后判是否有桶超过 2k2k2k 即可。

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=2e6+100;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
int n,m;
int bac[12];
signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();for(int i=1;i<=4;i++){for(int j=1;j<=4;j++){char c;scanf(" %c",&c);if(c!='.') bac[c-'0']++;//debug("%d\n",c-'0');}}for(int i=1;i<=9;i++){if(bac[i]>2*n){printf("NO\n");return 0;}}printf("YES\n");return 0;
}
/**/

CF373B Making Sequences is Fun

Description\text{Description}Description

定义 S(i)=iS(i)=iS(i)=i 的位数,如 S(893)=3,S(114514)=6S(893)=3,S(114514)=6S(893)=3,S(114514)=6

xxx 的费用为 k×S(i)k\times S(i)k×S(i)

你有 www 元钱,要从 mmm 开始连续添加尽量多的数 (m,m+1,m+2,⋯)(m,m+1,m+2,\cdots)(m,m+1,m+2,) 组成一个序列,问这个序列最长有多长。
w,m≤1016,k≤109w,m\le 10^{16},k\le10^9w,m1016,k109

Solution\text{Solution}Solution

小清新模拟。
可以先令 w←⌊wk⌋w\gets \lfloor \dfrac{w}{k}\rfloorwkwkkk 的影响去掉。
一直往进位处跳直到不能继续跳位置,然后把剩下的个数求出来,过程中贡献加起来即可。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=2e6+100;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
int n;
ll w,m,k;
inline ll calc(ll x){int res(0);while(x) x/=10,++res;return res;
}
ll mi[20];
signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifmi[1]=1;for(int i=2;i<=18;i++) mi[i]=mi[i-1]*10;w=read();m=read();k=read();w/=k;ll o=calc(m),ans(0);while((mi[o+1]-m)*o<=w){ans+=mi[o+1]-m;w-=(mi[o+1]-m)*o;++o;m=mi[o];//printf("o=%lld w=%lld ans=%lld m=%lld\n",o,w,ans,m);}  ans+=w/o;printf("%lld\n",ans);return 0;
}
/*
*/

CF372A Counting Kangaroos is Fun

Description\text{Description}Description

nnn 只袋鼠,每只的大小为 sis_isi,每只大小为 xxx 的袋鼠可以装在大小不少于 2x2x2x 的袋鼠的袋子里。
每只袋鼠的袋子最多装一只袋鼠,且装在别的袋鼠袋子里的袋鼠不能继续装袋鼠(不能套娃),求最多能让多少只袋鼠被装入别的袋鼠的袋子。

Solution\text{Solution}Solution

一道本人做的不太好的题。
一开始显然是想贪心,比如从大往小选,每个尽可能装大的之类,但是都可以被轻易的 hack。
然后就写了个垃圾的二分多只 log 艹过去了

下面讲线性的贪心正解。
其实刚才朴素的贪心是可以借鉴的,唯一的错误就在与尽可能装的的那只“大袋鼠”可能用来装别的袋鼠。

证明:
由于装的个数最多肯定不超过 n/2n/2n/2 个,所以最小的 n/2n/2n/2 只袋鼠肯定不会装别人。
同时,如果某只袋鼠装了一只不在这 n/2n/2n/2 只袋鼠里的袋鼠,那它改成这 n/2n/2n/2 只袋鼠中没有被装的一只(必然存在)也是不劣的。
所以这个贪心是真的。

维护双指针从 n/2n/2n/2 开始尽可能的装大的即可。

Code\text{Code}Code

(双指针的代码题解区很多了,这里就贴的一开始二分的码,也算是另一种思路)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=2e6+100;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
int n;
int a[N];
bool check(int k){int l=1,r=k+1;while(l<=k){while(r<n&&a[r]<2*a[l]) ++r;if(a[r]<2*a[l]) return false;++l;++r;}return true;
}
signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();for(int i=1;i<=n;i++) a[i]=read();sort(a+1,a+1+n);int st=0,ed=n/2;while(st<ed){int mid=(st+ed+1)>>1;if(check(mid)) st=mid;else ed=mid-1;}printf("%d\n",n-st);return 0;
}
/*
*/

CF372B Counting Rectangles is Fun

Description\text{Description}Description

给定一个 n∗m{n * m}nm0/10/10/1 矩阵, qqq 次询问, 每次询问指定一个子矩形, 求该子矩形种有多少个只包含 000 的子矩阵。
n,m≤40,q≤3×105n,m\le40,q\le3\times 10^5n,m40,q3×105

Solution\text{Solution}Solution

小清新水紫。
似乎已经把 O(nmq)O(nmq)O(nmq) 的复杂度写在数据范围上了…
考虑枚举这个矩形的长和宽,那么剩下的就只能 O(1)O(1)O(1) 查询。
不难想到前缀和
定义一个矩阵的坐标为右下点的坐标
按照这个坐标的定义对于每个长和宽 (a,b)(a,b)(a,b) 都 预处理出矩形个数的前缀和,复杂度 O(n2m2)O(n^2m^2)O(n2m2)
那么我们如果在 (x1,y1,x2,y2)(x1,y1,x2,y2)(x1,y1,x2,y2) 的矩形中询问大小为 a×ba\times ba×b 的矩形,就相当于查询坐标在 (x1+a−1,y1+b−1,x2,y2)(x1+a-1,y1+b-1,x2,y2)(x1+a1,y1+b1,x2,y2) 这个矩形内的 a×ba\times ba×b 的矩形的总个数。
总时间复杂度 O(n2m2+qnm)O(n^2m^2+qnm)O(n2m2+qnm)

PS:本题由于那个四维前缀和数组跨度太大,请务必**把记录长宽的两维开在后面!**这样在回答询问的时候始终是连续访问,否则会由于过多的 cache miss 而超时…(至少对于我的垃圾码是这样)改完后跑的飞快毫无压力。

后来看题解似乎有 O(n2m2)−O(1)O(n^2m^2)-O(1)O(n2m2)O(1) 的神奇偏序前缀和魔法操作,也很妙。

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=2e6+100;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
int n,m,q;
int sum[50][50],num[50][50][50][50];
inline int Sum(int x1,int y1,int x2,int y2){return sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1];
}
/*inline int Num(int a,int b,int x1,int y1,int x2,int y2){return num[a][b][x2][y2]-num[a][b][x1-1][y2]-num[a][b][x2][y1-1]+num[a][b][x1-1][y1-1];
}*/
#define Num(a,b,x1,y1,x2,y2) num[x2][y2][a][b]-num[x1-1][y2][a][b]-num[x2][y1-1][a][b]+num[x1-1][y1-1][a][b]
signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();m=read();q=read();for(int i=1;i<=n;i++){for(int j=1;j<=m;j++) scanf("%1d",&sum[i][j]);}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++) sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];}for(int a=1;a<=n;a++){for(int b=1;b<=m;b++){for(int i=a;i<=n;i++){for(int j=b;j<=m;j++)num[i][j][a][b]=num[i-1][j][a][b]+num[i][j-1][a][b]-num[i-1][j-1][a][b]+(Sum(i-a+1,j-b+1,i,j)==0);}}}//debugfor(int i=1;i<=q;i++){int x1=read(),y1=read(),x2=read(),y2=read();int ans(0);for(int a=1;a<=x2-x1+1;a++){for(int b=1;b<=y2-y1+1;b++){ans+=Num(a,b,x1+a-1,y1+b-1,x2,y2);}}printf("%d\n",ans);}return 0;
}
/*
*/

CF372D Choosing Subtree is Fun

Description\text{Description}Description

有一棵 nnn 个结点的树,树上结点从 111nnn 标号。

定义树上一个连通子图的权值为最长的区间 [l,r][l,r][l,r] 的长度,满足标号在 [l,r][l,r][l,r] 之间的结点均在这个连通子图中。

现在请你求出树上所有的结点数量不超过 kkk 的连通子图的权值最大值。

Solution\text{Solution}Solution

大结论题。
做完本题可以水一下这个。

结论:一棵给定的树,若给出若干关键点,将其按照 dfs 序排序后为 a1...ka_{1...k}a1...k,则它们的最小导出子图的边权和为 dis(a1,a2)+dis(a2,a3)+...+dis(ak,a1)dis(a_1,a_2)+dis(a_2,a_3)+...+dis(a_k,a_1)dis(a1,a2)+dis(a2,a3)+...+dis(ak,a1) 的一半。
证明:每条边都会被算两遍。(感性理解一下

有这个结论后,本题就简单了。二分答案,然后双指针扫一遍,不断维护一个 set 计算当前导出图的边权和即可,点数就是再加一。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=1e5+100;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
int n,m;
struct node{int to,nxt;
}p[N<<1];
int fi[N],cnt;
inline void addline(int x,int y){p[++cnt]=(node){y,fi[x]};fi[x]=cnt;
}
int pl[N][20],pos[N],siz[N],tim,dep[N];
void dfs(int x,int fa){pos[x]=++tim;siz[x]=1;dep[x]=dep[fa]+1;pl[x][0]=fa;for(int k=1;pl[x][k-1];k++) pl[x][k]=pl[pl[x][k-1]][k-1];for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;if(to==fa) continue;dfs(to,x);siz[x]+=siz[to];}return;
}
inline int Lca(int x,int y){if(pos[x]<=pos[y]&&pos[y]<=pos[x]+siz[x]-1) return x;for(int k=17;k>=0;k--){int o=pl[x][k];if(!o||(pos[o]<=pos[y]&&pos[y]<=pos[o]+siz[o]-1)) continue;x=pl[x][k];//printf("k=%d x=%d\n",k,x);}return pl[x][0];
}
inline int dis(int x,int y){int lca=Lca(x,y);//printf("  dis: x=%d y=%d lca=%d res=%d\n",x,y,lca,dep[x]+dep[y]-2*dep[lca]);return dep[x]+dep[y]-2*dep[lca];
}
struct cmp{bool operator ()(const int a,const int b){return pos[a]<pos[b];}
};
set<int,cmp>s;
set<int,cmp>::iterator it;
int now;
inline int Pre(int x){it=s.find(x);if(it==s.begin()) return (*s.rbegin());else{it--;return (*it);}
}
inline int Nxt(int x){it=s.find(x);it++;if(it==s.end()) return (*s.begin());else return (*it);
}
inline void add(int x){if(s.empty()){s.insert(x);return;}s.insert(x);int pre=Pre(x),nxt=Nxt(x);now-=dis(pre,nxt);now+=dis(pre,x)+dis(x,nxt);return;
}
inline void del(int x){if(s.size()==1){s.erase(x);return;}int pre=Pre(x),nxt=Nxt(x);now-=dis(pre,x)+dis(x,nxt);now+=dis(pre,nxt);s.erase(x);return;
}
bool check(int k){now=0;s.clear();for(int i=1;i<=k;i++) add(i);if(now/2+1<=m) return true;//printf("(%d %d) now=%d\n",1,k,now);for(int i=k+1;i<=n;i++){del(i-k);add(i);//printf("(%d %d) now=%d\n",i-k+1,i,now);if(now/2+1<=m) return true;}return false;
}signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifmemset(fi,-1,sizeof(fi));cnt=-1;n=read();m=read();for(int i=1;i<n;i++){int x=read(),y=read();addline(x,y);addline(y,x);}dfs(1,0);//printf("lca=%d\n",Lca(2,1));//printf("check=%d\n",check(3));//return 0;int st=1,ed=n;while(st<ed){int mid=(st+ed+1)>>1;if(check(mid)) st=mid;else ed=mid-1;}printf("%d\n",st);return 0;
}
/*
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317268.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一二三系列之CodeChef分块——Chef and Churu,Chef and Problems,Children Trips

文章目录Chef and ChurusourcesolutioncodeChef and ProblemssourcesolutioncodeChildren TripssourcesolutioncodeChef and Churu source solution 对于单独的iii&#xff0c;查询可以用线段树/树状数组O(nlog⁡n)O(n\log n)O(nlogn)&#xff0c;这暗示可以平衡查询修改次数…

Bob‘s Problem

Bob’s Problem 题意&#xff1a; 一个有n个点的图&#xff0c;其中边分为白色和黑色&#xff0c;每个边都有边权&#xff0c;所选白边的数量的数量不能超过k&#xff0c;问现在选择一些边&#xff0c;使得所有点连通&#xff0c;问最大权值是多少&#xff1f; 题解&#xf…

.NET Core 开源项目 Anet 在路上

今天给大家介绍我刚开源的一个 .NET Core 项目&#xff1a;Anet。Anet 的目标是实现一个 .NET Core 通用库、通用框架和通用模板。我给它的定义是&#xff1a;A .NET Core Common Lib, Framework and Boilerplate.它的取名正是来自于这句话的前面四个字母&#xff1a;ANET。Ane…

Loj#2324-「清华集训 2017」小 Y 和二叉树

正题 题目链接:https://loj.ac/p/2324 题目大意 给出nnn个点的一棵树&#xff0c;每个点的度数不超过333。 你要求它的一个二叉树结构&#xff08;根任意选择&#xff09;使得其中序遍历的字典序最小。 1≤n≤1061\leq n\leq 10^61≤n≤106 解题思路 直接找根感觉比较麻烦&…

模板:后缀自动机(SAM)

所谓后缀自动机&#xff0c;就是通过后缀建立的自动机 &#xff08;逃&#xff09; 请允许我先介绍一下后缀家族&#xff1a; &#xff08;又逃&#xff09; 前言 OI生涯目前为止学习的最为难以理解的算法&#xff0c;没有之一。 到现在也没有完全的理解。 qwq 概念 定义&…

.NET 开源项目 Anet 介绍

使用 Anet 有一段时间了&#xff0c;已经在我的个人网站&#xff08;如 bookist.cc&#xff09;投入使用&#xff0c;目前没有发现什么大问题&#xff0c;所以才敢写篇文章向大家介绍。GitHub 地址&#xff1a;https://github.com/anet-team/anetAnet 是一个 .NET Core 通用框架…

线性代数问卷调查反馈——Find The Determinant III,Takahashi‘s Basics in Education and Learning

文章目录Find The Determinant IIIsourcecodeTakahashis Basics in Education and LearningsourcecodeFind The Determinant III source 高斯消元求行列式的模板题 code #include <cstdio> #include <iostream> using namespace std; #define maxn 205 #define…

L - Who is the Champion

L - Who is the Champion 计蒜客 - 42587 题意&#xff1a; 给出一个N阶矩阵&#xff0c;&#xff08; i , j &#xff09; &#xff08;i, j&#xff09;&#xff08;i,j&#xff09;处的数字表示这场比赛球队i ii踢进球队j jj多少球。两支球队平局则各加一分&#xff0c;一…

CF1037H Security(SAM)

解析 算是一个比较高级的SAM的应用了 对fail树的dfs序建立维护右端点最大值的线段树 考虑把所有的询问离线&#xff0c;按照右端点排序 每次动态把当前询问右端点左侧的前缀插入线段树 处理询问时&#xff0c;先贪心的尝试和询问串填法一样&#xff0c;如果不行就往下一个字母…

AT5147-[AGC036D]Negative Cycle【dp,模型转换】

正题 题目链接:https://www.luogu.com.cn/problem/AT5147 题目大意 有nnn个点的一张图&#xff0c;其中i→i1(i<n)i\rightarrow i1(i< n)i→i1(i<n)有一条边权值为000。 对于其他i,j(i≠j)i,j(i\neq j)i,j(ij)存在一条边i→ji\rightarrow ji→j&#xff0c;若i&l…

栈/队列/分块问卷调查反馈——Weak in the Middle,Cutting Plants,最小公倍数

文章目录Weak in the MiddlesourcesolutioncodeCutting Plantssourcesolutioncode[HNOI2016]最小公倍数sourcesolutioncodeWeak in the Middle source solution 栈模拟。 天数的计算&#xff0c;可以发现与其参与三元比较的次数有关 对于栈顶&#xff0c;如果被弹出&#…

我的十年创业路

记十年创业的心路历程和我的创业思辨导读1 为什么写这篇文章2 详细的总结和思辨 2.01 感恩 2.02 为什么创业 2.03 十年流水账 2.04 经历了哪些失败 2.05 重要的职场基础 2.06 持续的学习和进步 2.07 创业与兴趣 2.08 价值观的碰撞和选择 2.09 合作与…

C - And and Pair

C - And and Pair 题意&#xff1a; 问有多少组(i,j)满足要求。 要求为&#xff1a; 0<j<i<n i&ni i&j0 答案mod 1e97 题解&#xff1a; 这个和我的思路时一样的&#xff0c;且讲的更清楚 i&ni说明n为0的地方&#xff0c;i必须为0&#xff1b;n为1的地…

CF850F Rainbow Balls(数学、期望)

解析 二倍相邻项&#xff0c;就要想裂项 纯数学题 一道黑色的小凯的疑惑 设总球数为 sss 我们先钦定一种颜色留到最后&#xff0c;那么其他颜色可以等价考虑 设 fif_{i}fi​ 为钦定的颜色的球有 iii 个&#xff0c;涂完需要的期望次数 则有&#xff1a; fi(fi−1fi1)pfi(1−2p…

pjudge#21652-[PR #4]到底有没有九【数位dp】

正题 题目链接:http://pjudge.ac/problem/21652 题目大意 给出一个正整数kkk&#xff0c;求第nnn个xxx满足x(10k−1)x\times (10^k-1)x(10k−1)中没有一个数位为999。 1≤n≤1018,1≤k≤181\leq n\leq 10^{18},1\leq k\leq 181≤n≤1018,1≤k≤18 解题思路 首先是从高位到低…

专题突破二之优先队列、st表——,Running Median,Sequence,Buy Low Sell High,数据备份,超级钢琴,ZQC的手办

文章目录Running MedianSequenceBuy Low Sell High[APIO/CTSC 2007] 数据备份[NOI2010] 超级钢琴「LibreOJ β Round」ZQC 的手办Running Median source 对顶栈 用大根堆和小根堆一起维护 若元素小于等于大根堆栈顶&#xff0c;放入大根堆否则放入小根堆 大根堆维护的就是…

G - Eating Plan

G - Eating Plan 题意&#xff1a; 一个1到n组成的排列&#xff0c;每个数的价值为其阶乘&#xff0c;有m个询问ki&#xff0c;要求你在排列中选取连续的一块&#xff0c;使得价值和mod 998857459 后&#xff0c;大于ki&#xff0c;问最短区间长度&#xff0c;如果不存在输出…

P4770:你的名字(SAM、线段树合并)

文章目录前言解析前言 1000A快乐&#xff01;&#xff01;&#xff01;awa 没有想象中的那么恶心。 解析 先考虑每次都询问 [1,n][1,n][1,n] 如何做。 正难则反&#xff0c;用T所有本质不同串数量减去是S串子串又是T的子串的数量 前者很好求&#xff0c;关键是后者 首先可以…

DotNetty 实现 Modbus TCP 系列 (一) 报文类

Modbus TCP/IP 报文报文最大长度为 260 byte (ADU 7 byte MBAP Header 253 byte PDU)Length Unit Identifier 长度 PDU 长度MBAP HeaderPDUPDU 由两部分构成&#xff1a;Function Code(功能码) 和 Data 组成Function Code部分功能码&#xff1a;报文类ModbusHeaderModbusHe…

AT2377-[AGC014E]Blue and Red Tree【启发式合并】

正题 题目链接:https://www.luogu.com.cn/problem/AT2377 题目大意 有两棵树T1,T2T_1,T_2T1​,T2​。T1T_1T1​树上的边开始时都是蓝色的&#xff0c;我们每次选择一条蓝色边路径(x,y)(x,y)(x,y)&#xff0c;然后删掉路径上一条边&#xff0c;连接一条xxx到yyy的红色边。 要…