整套都是牛客的原题所以就不设密码了(

原题页面:https://ac.nowcoder.com/acm/contest/65193

Statements & Solution:https://www.luogu.com.cn/problem/U507206

Solution:https://www.nowcoder.com/discuss/540225827162583040

\(60+30+20+20=130\)。

每日挂分之T2线段树不开\(4\)倍+\(10^6\)数量级输入不关同步流,\(\bf\colorbox{MidnightBlue}{\texttt{\color{White}{TLE}}}\ \ 100\to 30\)。

A

赛时光想着\(f[i][j]\)表示\(i\)个元素选\(j\)个的答案,磕了半天没想出来。

实际上这道题应该从值域为\(n\)这一特征入手,这子集之和最大是\(\frac{n(n+1)}{2}\)。

因此我们考虑枚举子集之和\(x\),用dp求出有多少种选法能达到这个子集和\(y\)。答案即为所有\(x^y\)相乘,用快速幂优化一下。

但是\(y\)可能非常大,但它作为指数不能直接取模。我们可以利用欧拉定理(其实就是费马小定理的推广)\(a^{\varphi(m)}\equiv1\pmod n\),将指数对\(\varphi(998244353)=998244352\)取模即可。

时间复杂度\(O(n^3)\)。

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define N 202
#define mod 998244353
using namespace std;
int n,f[N][N*N]={1},ans=1;
int qp(int a,int b){
int koishi=1;
while(b){
if(b&1) koishi=koishi*a%mod;
a=a*a%mod,b>>=1;
}
return koishi;
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=0;j<=n*(n+1)/2;j++){
f[i][j]=f[i-1][j];
if(j>=i) f[i][j]=(f[i][j]+f[i-1][j-i])%(mod-1);
}
}
for(int i=1;i<=n*(n+1)/2;i++) ans=ans*qp(i,f[n][i])%mod;
cout<<ans<<"\n";
return 0;
}

B

原题:P3488 [POI2009] LYZ-Ice Skates

我?赛时切紫?真的假的?!

假的 因为这个或那个的原因传奇地挂了\(70\)分,本来是可以切的。。。学到的:用cin一定要关同步流,线段树开\(4\)倍。


我们把每个住户选择的范围\([l,r]\)看作线段。

有解\(\iff\)对于所有区间,都有\(\bf x\le len\times k\)。其中\(\bf len\)是该区间的长度,\(\bf x\)是该区间覆盖的线段数。

  • 充分性:\(len\times k\)就是这个区间内的房间数量,所以如果该区间内的住户数量\(>\)房间数量,那么房间是不够用的。
  • 必要性:显然,无解\(\iff\)存在长度为\(d+1\)的区间不合法,那么有解\(\iff\)所有长度为\(d+1\)的区间都合法。

    在有解时考虑最极端的情况,即最大化\(x\)。显然此时需要\(d=0\),且所有长度为\(d+1\)的区间都放满了\(k\)条线段,那么总共覆盖的线段数量\(x=(len-d)\times k=len\times k\)。在有解的情况下\(x\)最大取到\(len\times k\),所以\(x\le len\times k\Rightarrow\)有解。

于是我们只需要判断该结论是否成立即可。

由于区间等长,我们简化一下,只统计区间左端点,判断是否存在区间\([l,r]\)使得\(x\le (len+d)\times k\),其中\(len=r-l+1\),\(x\)是\([l,r]\)覆盖的左端点个数。

这样还是不太容易看,我们移一下项:\(x-len\times k\le d\times k\)。

其中\(d\times k\)是常数,所以我们把\((x-len\times k)\)看作一个整体扔进线段树维护即可,具体来说,将线段树叶子节点初值赋为\(-k\)即可。这种把位置相关量看作一个整体来维护的技巧之前洛谷比赛有过:P11157 【MX-X6-T3】さよならワンダーランド ~ 题解

由于只要存在\((x-len\times k)>d\times k\)就是不合法的。所以我们需要想办法维护出那个\((x-len\times k)\)最大的区间来与\(d\times k\)进行比较。所以我们用线段树来维护一个最大连续子段和,模板题 P4513 小白逛公园,转移并不难理解,可以去看下洛谷的题解。

这样求出最大连续子段和,判定答案并输出即可。时间复杂度\(O(n\log n)\)。

点击查看代码
#include<bits/stdc++.h>
#define lc(x) ((x)<<1)
#define rc(x) ((x)<<1|1)
#define int long long
#define N 500010
using namespace std;
int n,m,k,d,sum[N<<2],maxx[N<<2],lmax[N<<2],rmax[N<<2];
void update(int x){
sum[x]=sum[lc(x)]+sum[rc(x)];
maxx[x]=max({maxx[lc(x)],maxx[rc(x)],rmax[lc(x)]+lmax[rc(x)]});
lmax[x]=max({lmax[lc(x)],sum[lc(x)]+lmax[rc(x)]});
rmax[x]=max({rmax[rc(x)],sum[rc(x)]+rmax[lc(x)]});
}
void build(int x,int l,int r){
if(l==r){
sum[x]=-k;
return;
}
int mid=(l+r)>>1;
build(lc(x),l,mid),build(rc(x),mid+1,r);
update(x);
}
void chp(int a,int v,int x,int l,int r){
if(l==r){
sum[x]+=v;
lmax[x]=rmax[x]=maxx[x]=max(0ll,sum[x]);
return;
}
int mid=(l+r)>>1;
if(a<=mid) chp(a,v,lc(x),l,mid);
else chp(a,v,rc(x),mid+1,r);
update(x);
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>n>>m>>k>>d;
build(1,1,n-d);
int x,y;
while(m--){
cin>>x>>y;
chp(x,y,1,1,n-d);
if(maxx[1]>d*k) cout<<"NO\n";
else cout<<"YES\n";
}
return 0;
}

C

目前全网只能找到原比赛页面的题解了,但是看不懂,std也挺玄学的,\(f\)的含义都没搞懂……

先把自己的暴力和照着std写的代码放上来,等弄懂了会更新。

暴力的做法就是二进制枚举每个元素是否被选,然后先判断是否连通,再看连通块是否满足\(m\)个约束条件。

暴力
#include<bits/stdc++.h>
#define int long long
#define N 2010
#define M 25
using namespace std;
struct Limit{int u,v;}lim[M];
int n,m,v[N],ans,dep[N],koishi[N],idx,V;
bitset<N> sel[N];
vector<int> G[N];
void satori(int u,int fa){
dep[u]=dep[fa]+1;
for(int i:G[u]) satori(i,u);
}
void dfs(int u){
koishi[++idx]=u,V+=v[u];
for(int i:G[u]) if(sel[i]==1) dfs(i);
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>v[i];
for(int i=1,s,v;i<=n;i++){
cin>>s;
while(s--) cin>>v,G[i].emplace_back(v);
}
satori(1,0);
for(int i=1;i<=m;i++) cin>>lim[i].u>>lim[i].v;
for(int i=(1<<n)-1;i;i--){
int mindep=INT_MAX,p=-1,pc=0;
for(int j=1;j<=n;j++) sel[j]=(i>>(j-1))&1,pc+=(sel[j]==1);
for(int j=1;j<=n;j++) if(sel[j]==1&&dep[j]<mindep) mindep=dep[j],p=j;
idx=V=0,dfs(p);
if(idx!=pc) continue;
bool f=1;
for(int j=1;j<=m;j++){
for(int k=1;k<idx;k++){
if((koishi[k]==lim[j].u&&koishi[k+1]==lim[j].v)||(koishi[k]==lim[j].v&&koishi[k+1]==lim[j].u)){
f=0;
break;
}
}
if(f==0) break;
}
if(f) ans=max(ans,V);
}
cout<<ans<<"\n";
return 0;
}
STD
#include<bits/stdc++.h>
#define int long long
#define N 100010
#define M 52//开2倍,因为无向
using namespace std;
int n,m,a[N],num[N],idx,ans,f[N][M];
struct t_edge{int u,v;}dat[M];
vector<int> G[N];
bitset<N> vis;
bitset<M> mp[M];
void dfs(int u){
f[u][num[u]]=a[u];
for(int i:G[u]){
dfs(i);
int maxx=LLONG_MIN;
for(int j=0;j<=idx;j++) if(!mp[j][num[i]]) maxx=max(maxx,f[u][j]);
for(int j=0;j<=idx;j++) f[u][j]=max(f[u][j],f[i][j]+maxx);
}
for(int i=0;i<=idx;i++) ans=max(ans,f[u][i]);
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1,s,v;i<=n;i++){
cin>>s;
while(s--) cin>>v,G[i].push_back(v);
}
for(int i=1,u,v;i<=m;i++){
cin>>u>>v;
dat[i]={u,v};
vis[u]=vis[v]=1;
}
for(int i=1;i<=n;i++) if(vis[i]) num[i]=++idx;
for(int i=1;i<=m;i++){
int u=num[dat[i].u],v=num[dat[i].v];
mp[u][v]=mp[v][u]=1;
}
memset(f,-0x3f,sizeof f),dfs(1);
for(int i=1;i<=n;i++){
for(int j=0;j<=idx;j++){
cout<<i<<" "<<j<<" : "<<f[i][j]<<"\n";
}
}
cout<<ans<<"\n";
return 0;
}

D

这个有空再看。\(n\le 20\)的暴力思路就是将\(01\)串压成一个数,先二进制枚举问号处填什么,再对于每一种填法,跑DFS,记录能跑到的状态种数,累加答案。

暴力
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#define N 514//無意識
#define mod 1000000007
using namespace std;
using namespace __gnu_pbds;
int n,un[N],idx,num,ans;
string s;
gp_hash_table<int,bool> vis;
bool getp(int x,int pos){return (x>>pos)&1;}
void dfs(int x){
if(vis[x]) return;
vis[x]=1;
for(int i=2;i<n;i++){
if(!getp(x,i-2)&&getp(x,i-1)&&getp(x,i)) dfs((x|(1<<(i-2)))&(~(1<<i)));
else if(getp(x,i-2)&&getp(x,i-1)&&!getp(x,i)) dfs((x|(1<<i))&(~(1<<(i-2))));
}
}
void solve(int x){
vis.clear();
dfs(x);
ans=(ans+vis.size())%mod;
}
signed main(){
cin>>n>>s;
for(int i=0;i<n;i++){
if(s[i]=='?') un[++idx]=i;
else if(s[i]=='1') num|=(1<<i);
}
for(int i=(1<<idx)-1;~i;i--){
int tnum=num;
for(int j=0;j<idx;j++)
if(getp(i,j)) tnum|=(1<<un[j+1]);
solve(tnum);
}
cout<<ans<<"\n";
return 0;
}
STD
#include <bits/stdc++.h>

using namespace std;

#define lep(i, l, r) for(int i = (l); i <= (r); i ++)
#define rep(i, l, r) for(int i = (l); i >= (r); i --) const int N = 500 + 5;
const int P = 1e9 + 7; inline int mod(int x) { return x + (x >> 31 & P); }
inline void pls(int &x, int y) { x = mod(x + y - P); } int power(int x, int k) {
int res = 1;
while(k) {
if(k & 1) res = 1ll * res * x % P;
x = 1ll * x * x % P; k >>= 1;
} return res;
} int n;
int F[N][N][2], G[N][N][2];
char str[N]; int fac[N], ifac[N];
inline int C(int x, int y) {
if(x < 0 || y < 0 || x < y) return 0;
return 1ll * fac[x] * ifac[y] % P * ifac[x - y] % P;
} int main() {
ios :: sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n; cin >> (str + 1);
auto f = F;
auto g = G;
f[0][0][0] = 1;
lep (i, 1, n) {
memset(g, 0, sizeof(G));
lep (j, 0, i) lep (k, 0, i) lep (op, 0, 1) if(f[j][k][op]) {
char ch = str[i];
if(ch == '0' || ch == '?')
pls(g[j][k + 1][0], f[j][k][op]);
if(ch == '1' || ch == '?') {
if(op == 1) pls(g[j + 1][k][0], f[j][k][op]);
else pls(g[j][k][1], f[j][k][op]);
}
}
swap(f, g);
}
fac[0] = 1;
lep (i, 1, n) fac[i] = 1ll * fac[i - 1] * i % P;
ifac[n] = power(fac[n], P - 2);
rep (i, n - 1, 0) ifac[i] = 1ll * ifac[i + 1] * (i + 1) % P;
int ans = 0;
lep (i, 0, n) lep (j, 0, n) if(f[i][j][0] || f[i][j][1]) {
int res = mod(f[i][j][0] + f[i][j][1] - P);
ans = (ans + 1ll * res * C(i + j, i)) % P;
}
printf("%d\n", ans);
return 0;
}

[题解][test05]2024/11/21 模拟赛 / 2023牛客OI赛前集训营-提高组(第二场) A~B的更多相关文章

  1. 2021牛客OI赛前集训营-提高组(第三场) 第二题 交替 题解与结论证明

    题目描述 一个长度为 \(n\) 的数组\(A\),每秒都会变成一个长度为 \(n − 1\) 新数组 \(A'\),其变化规 则如下: 若当前数组 \(A\) 的长度 \(n\) 为偶数,则对于新数 ...

  2. 2021牛客OI赛前集训营-提高组(第二场)第三题 树数树题解

    题目描述 牛牛有一棵 \(n\) 个点的有根树,根为 \(1\). 我们称一个长度为 \(m\) 的序列 \(a\) 是好的,当且仅当: \(\forall i \in (1,m]\),\(a_i\) ...

  3. 2020牛客NOIP赛前集训营-普及组(第二场) 题解

    目录 T1 面试 描述 题目描述 输入描述: 输出描述: 题解 代码 T2 纸牌游戏 描述 题目描述 输入描述: 输出描述: 题解 代码 T3 涨薪 描述 题目描述 输入描述: 输出描述: 题解 代码 ...

  4. 比赛总结——牛客网 NOIP赛前集训营提高组模拟第一场

    第一场打的很惨淡啊 t1二分+前缀最小值没想出来,20分的暴力也挂了,只有10分 t2数位dp,调了半天,结果因为忘了判0的特殊情况WA了一个点,亏死 t3emmmm.. 不会 imone说是DSU ...

  5. [NowCoder]牛客网NOIP赛前集训营-提高组(第六场)题解

    A.最长路 题意:给定有向图,每条边有个字符\([0,10^9]\),求每个点最长路字典序最小的方案.\(N,M\le 10^6\) 建反图跑拓扑排序,显然入过队的点都有最长路,考虑如何判断字典序大小 ...

  6. Nowcoder | [题解-N165]牛客网NOIP赛前集训营-普及组(第二场)

    啊...表示一大早还没睡醒就开始打比赛(开始前一分钟的我还在桌子上趴着休眠)...表示题目思路清奇(尤其C题)...但是我还是太蒻了...\(D\)题暴力都没打...题解正式开始之前先\(\%\)一下 ...

  7. 18/9/21模拟赛-Updated

    18/9/21模拟赛 期望得分:100:实际得分:0  qwq 拿到题目第一眼,我去,这不是洛谷原题(仓鼠找Sugar)吗 又多看了几眼,嗯,对,除了是有多组数据外,就是原题 然后码码码....自以为 ...

  8. 9.11 myl模拟赛

    9.11 myl 模拟赛 100 + 100 + 0 第一题耗费了太多的时间,导致最后一题没有时间想,直接去写了暴力,而且出题人没有给暴力分.... Problem 1. superman [题目描述 ...

  9. 牛客OI赛制测试赛2(0906)

    牛客OI赛制测试赛2(0906) A :无序组数 题目描述 给出一个二元组(A,B) 求出无序二元组(a,b) 使得(a|A,b|B)的组数 无序意思就是(a,b)和(b,a) 算一组. 输入描述: ...

  10. 牛客OI月赛12-提高组题解

    牛客OI月赛12-提高组 当天晚上被\(loli\)要求去打了某高端oj部分原创的模拟赛,第二天看了牛客的题觉得非常清真,于是就去写了 不难发现现场写出\(260\text{pts}\)并不需要动脑子 ...

随机推荐

  1. Spring 注解之@RequestHeader注解:获取请求头参数

    基本用法   Spring MVC提供了 @RequestHeader注解,其作用是将请求头中的参数值映射到控制器的参数中.常用属性如下: name:header值被绑定到的参数名称(The name ...

  2. java如何启动时定义并初始化一个全局变量(内存中)

    前言 java如何启动时定义并初始化一个全局变量(内存中),项目启动时,通过读取配置文件来构建一个实体类对象,然后在之后可以直接使用,而不是每次使用都要进行构建 前置准备 实体类结构 package ...

  3. 以RRT为例分析创新点的产生

    1.找到基本算法的问题 1.1 喂文章和专利给GPT并分析提出的问题 1.2 整理问题 分析当前问题属于基本算法的那个阶段 2.1 固定参数问题:以双向RRT为例子:步长.采样方向.局部优化范围.交换 ...

  4. Strands Agents(一)Strands Agents 介绍

    Strands Agent AWS 最新开源的 Strands Agents SDK 是一款采用模型驱动架构的 AI 代理开发框架,旨在通过极简开发方式,帮助开发者快速构建和部署 AI 代理.它将代理 ...

  5. PI发布rest,json接口

    PI接口的开发分成两个部分,第一个部分是ESB(Enterprise Services Builder)部分,这里注意做数据结构定义,接口导入,字段关系映射,定义接口等. 第二部分是IB(Integr ...

  6. 一站式运维管家 ChengYing 主机接入原理解析

    之前的文章中,我们已经为大家介绍了 ChengYing 的安装原理.产品包制作.产品线部署等内容,本篇将和大家介绍一个困扰许多开发者的内容--ChengYing 主机接入.帮助所有对 ChengYin ...

  7. Kafka入门实战教程(4):重要的集群参数配置

    1 如何规划Kafka 集群部署"兵马未动,粮草先行",与其盲目上马一套Kafka环境然后事后费力调整,不如一开始就思考好实际场景下业务所需的集群环境.在考量部署方案时需要通盘考虑 ...

  8. H20 大模型推理系统环境配置踩坑

    基础环境 CPU:INTEL(R) XEON(R) PLATINUM 8558P 48 Cores 96 Threads × 2 GPU:NVIDIA H20-3e NVL 141G × 8,NVLI ...

  9. [CSP-S 2022] 假期计划

    link \(1-A-B-C-D-1\) 非常对称,我们断开来,分成 \(1-A-B\) 和 \(C-D-1\) 两部分,不难发现这两块是完全一致的. 首先对于每个景点 \(x\) 求出距离它不过 K ...

  10. java-Spring事务管理、SH整合

    程序中事务控制 事务控制概述 编程式事务控制 自己手动控制事务,就叫做编程式事务控制. Jdbc代码: Conn.setAutoCommite(false); // 设置手动控制事务 Hibernat ...