CSP-S 模拟赛 34

news/2024/10/7 12:53:43/文章来源:https://www.cnblogs.com/laoshan-plus/p/18449918

CSP-S 模拟赛 34

rnk12,\(24+50+20+0=94\)

T1 玩游戏

有一个痿正解:从 \(k\)\(1\) 扫左端点,对于每个左端点扫它最远能到达的右端点。如果在任何一时刻它的右端点位置 \(<k\),则断定输出 No。否则检查当左端点到 \(1\) 时右端点能否到 \(n\)。注意这里扫右端点的方式,不要每次都从 \(k\) 向右扫,而是把右端点定义在外面,然后用和莫队类似的那种方法扫,就极大地降低了复杂度。实测最终 TLE 91pts,很可以了。

考场上连这都想不到?该退役了。

真正的正解貌似更复杂?唐了。

#include<bits/stdc++.h>
#define fw fwrite(obuf,p3-obuf,1,stdout)
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
#define putchar(x) (p3-obuf<1<<20?(*p3++=(x)):(fw,p3=obuf,*p3++=(x)))
using namespace std;char buf[1<<20],obuf[1<<20],*p1=buf,*p2=buf,*p3=obuf,str[20<<2];
template<typename T=int>
T read(){T x=0,f=1;char ch=getchar();while(!isdigit(ch))ch=='-'&&(f=-1),ch=getchar();while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar();return x*f;
}
template<typename T>
void write(T x,char sf='\n'){if(x<0)putchar('-'),x=~x+1;int top=0;do str[top++]=x%10,x/=10;while(x);while(top)putchar(str[--top]+48);if(sf^'#')putchar(sf);
}
void writes(string s){for(auto x:s)putchar(x);putchar('\n');
}
using ll=long long;
constexpr int MAXN=1e5+5;
int T,n,k;
ll a[MAXN],sum[MAXN];int main(){freopen("game.in","r",stdin);freopen("game.out","w",stdout);T=read();while(T--){n=read(),k=read();memset(sum,0,sizeof(ll)*(n+5));for(int i=1;i<=n;++i)a[i]=read<ll>();if(sum[n]-sum[1]>0){writes("No");continue;}for(int i=k-1;i;--i)sum[i]=sum[i+1]+a[i+1];for(int i=k+1;i<=n;++i)sum[i]=sum[i-1]+a[i];int r=k;for(int i=k;i;--i){while(sum[r+1]+sum[i]<=0&&r<n)++r;while(sum[r]+sum[i]>0&&r)--r;if(r<k){writes("No");goto byby;}}writes(r==n?"Yes":"No");byby:;}return fw,0;
}

T2 排列

不用笛卡尔树。设 \(f_{i,j,0/1,0/1}\) 表示长度为 \(i\) 的区间 \(j\) 次合并完,左右两边是否靠墙的前缀和。用前缀和优化 DP。

  • 对于 00 的情况(两边都靠墙),可以由 \(j\) 相同的 01 和 10 转移。
  • 对于 10 的情况,可以由 \(j-1\) 的 11 和 \(j\) 相同的 10 转移。
  • 对于 01 的情况,同理。
  • 对于 11 的情况,前缀和神秘转移。

神秘题没什么好说的。

#include<bits/stdc++.h>
#define fw fwrite(obuf,p3-obuf,1,stdout)
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
#define putchar(x) (p3-obuf<1<<20?(*p3++=(x)):(fw,p3=obuf,*p3++=(x)))
#define int long long 
using namespace std;char buf[1<<20],obuf[1<<20],*p1=buf,*p2=buf,*p3=obuf,str[20<<2];
template<typename T=int>
T read(){T x=0,f=1;char ch=getchar();while(!isdigit(ch))ch=='-'&&(f=-1),ch=getchar();while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar();return x*f;
}
template<typename T>
void write(T x,char sf='\n'){if(x<0)putchar('-'),x=~x+1;int top=0;do str[top++]=x%10,x/=10;while(x);while(top)putchar(str[--top]+48);if(sf^'#')putchar(sf);
}
constexpr int MAXN=1005;
int n,K,P;
int C[MAXN][MAXN];
int f[MAXN][MAXN][2][2];
void add(int&x,int y){x=x+y>=P?x+y-P:x+y;
}
int sub(int x,int y){return x-y<0?x-y+P:x-y;
}signed main(){freopen("per.in","r",stdin);freopen("per.out","w",stdout);n=read(),K=read(),P=read();for(int i=0;i<=n;++i){C[i][0]=1;for(int j=1;j<=i;++j)C[i][j]=(C[i-1][j]+C[i-1][j-1])%P/*,write(C[i][j])*/;}for(int i=0;i<=K;++i)f[0][i][0][0]=f[0][i][0][1]=f[0][i][1][0]=f[0][i][1][1]=1;for(int i=1;i<=n;++i)for(int k=1;k<=K;++k)for(int j=1;j<=i;++j){add(f[i][k][0][0],f[j-1][k][0][1]*f[i-j][k][1][0]%P*C[i-1][j-1]%P);add(f[i][k][0][1],f[j-1][k][0][1]*f[i-j][k-1][1][1]%P*C[i-1][j-1]%P);add(f[i][k][1][0],f[j-1][k-1][1][1]*f[i-j][k][1][0]%P*C[i-1][j-1]%P);add(f[i][k][1][1],sub(f[j-1][k][1][1]*f[i-j][k][1][1]%P,sub(f[j-1][k][1][1],f[j-1][k-1][1][1])*sub(f[i-j][k][1][1],f[i-j][k-1][1][1])%P)*C[i-1][j-1]%P);}write(sub(f[n][K][0][0],f[n][K-1][0][0]));return fw,0;
}

T3 最短路

假做法:两遍 Dijkstra。

真假做法:对于每一条边建一条反边,跑二维 Dij。设 \(\mathit{dis}_{i,j}\) 表示沿正边到 \(i\) 点和反边到 \(j\) 的距离之和,则 \(\mathit{dis}_{n,n}\) 即为题中所求。用 bitset 维护原本的 \(\mathit{vis}\) 数组。

#include<bits/stdc++.h>
#define fw fwrite(obuf,p3-obuf,1,stdout)
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
#define putchar(x) (p3-obuf<1<<20?(*p3++=(x)):(fw,p3=obuf,*p3++=(x)))
using namespace std;char buf[1<<20],obuf[1<<20],*p1=buf,*p2=buf,*p3=obuf,str[20<<2];
template<typename T=int>
T read(){T x=0,f=1;char ch=getchar();while(!isdigit(ch))ch=='-'&&(f=-1),ch=getchar();while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar();return x*f;
}
template<typename T>
void write(T x,char sf='\n'){if(x<0)putchar('-'),x=~x+1;int top=0;do str[top++]=x%10,x/=10;while(x);while(top)putchar(str[--top]+48);if(sf^'#')putchar(sf);
}
constexpr int MAXN=255;
int n,m,p[MAXN];
int hd1[MAXN],tot1,hd2[MAXN],tot2;
struct{int v,nxt;}e1[MAXN*MAXN],e2[MAXN*MAXN];
void addedge(int typ,int u,int v){if(typ==1){e1[++tot1]={v,hd1[u]};hd1[u]=tot1;}else{e2[++tot2]={v,hd2[u]};hd2[u]=tot2;}
}
struct Node{int s,x,y;Node(){}Node(int s,int x,int y):s(s),x(x),y(y){}bool operator<(const Node&b)const{return s>b.s;}
};
int dis[MAXN][MAXN],vis[MAXN][MAXN];
bitset<MAXN>bit[MAXN][MAXN];
void dijkstra(){memset(dis,0x3f,sizeof(dis));dis[1][1]=p[1];bit[1][1][1]=1;priority_queue<Node>q;q.emplace(dis[1][1],1,1);while(!q.empty()){int x=q.top().x,y=q.top().y;q.pop();if(vis[x][y])continue;vis[x][y]=1;for(int i=hd1[x],tmp;i;i=e1[i].nxt){tmp=0;if(!bit[x][y][e1[i].v])tmp=p[e1[i].v];if(dis[e1[i].v][y]>dis[x][y]+tmp){dis[e1[i].v][y]=dis[x][y]+tmp;bit[e1[i].v][y]=bit[x][y];bit[e1[i].v][y][e1[i].v]=1;q.emplace(dis[e1[i].v][y],e1[i].v,y);}}for(int i=hd2[y],tmp;i;i=e2[i].nxt){tmp=0;if(!bit[x][y][e2[i].v])tmp=p[e2[i].v];if(dis[x][e2[i].v]>dis[x][y]+tmp){dis[x][e2[i].v]=dis[x][y]+tmp;bit[x][e2[i].v]=bit[x][y];bit[x][e2[i].v][e2[i].v]=1;q.emplace(dis[x][e2[i].v],x,e2[i].v);}}}
}int main(){freopen("tour.in","r",stdin);freopen("tour.out","w",stdout);n=read(),m=read();for(int i=1;i<=n;++i)p[i]=read();for(int i=1,u,v;i<=m;++i){u=read(),v=read();addedge(1,u,v),addedge(2,v,u);}dijkstra();write(dis[n][n]==0x3f3f3f3f?-1:dis[n][n]);return fw,0;
}

T4 矩形

扫描线 + 并查集。讲得很清楚了。

#include<bits/stdc++.h>
#define fw fwrite(obuf,p3-obuf,1,stdout)
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
#define putchar(x) (p3-obuf<1<<20?(*p3++=(x)):(fw,p3=obuf,*p3++=(x)))
using namespace std;char buf[1<<20],obuf[1<<20],*p1=buf,*p2=buf,*p3=obuf,str[20<<2];
template<typename T=int>
T read(){T x=0,f=1;char ch=getchar();while(!isdigit(ch))ch=='-'&&(f=-1),ch=getchar();while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar();return x*f;
}
template<typename T>
void write(T x,char sf='\n'){if(x<0)putchar('-'),x=~x+1;int top=0;do str[top++]=x%10,x/=10;while(x);while(top)putchar(str[--top]+48);if(sf^'#')putchar(sf);
}
constexpr int MAXN=1e5+5;
int n,f[MAXN];
int find(int x){if(f[x]^x)f[x]=find(f[x]);return f[x];
}
void combine(int u,int v){int fu=find(u),fv=find(v);if(fu^fv)f[fu]=fv;
}
struct JUX{int x1,y1,x2,y2;bool operator<(const JUX&b)const{return y1<b.y1;}
}a[MAXN];
bool check(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){if(x2<x3||x4<x1||y2<y3||y4<y1)return 0;return 1;
}namespace zj{
#define lp p<<1
#define rp p<<1|1
#define mid ((s+t)>>1)
struct SegTree{int id,lim,typ,lazy;
}st[MAXN<<2];
void pushup(int p){if(st[lp].id==st[rp].id){st[p].id=st[lp].id;st[p].lim=st[lp].lim;st[p].typ=0;}else st[p].typ=1;if(st[lp].typ||st[rp].typ)st[p].typ=1;
}
void pushdown(int p){if(!st[p].lazy)return;st[lp].lazy=st[rp].lazy=1;st[lp].id=st[rp].id=st[p].id;st[lp].lim=st[rp].lim=st[p].lim;st[p].lazy=0;
}
void mdf(int l,int r,int lim,int id,int s=1,int t=1e5,int p=1){if(l<=s&&t<=r&&!st[p].typ){if(st[p].lim>lim)return;st[p].lazy=1,st[p].id=id,st[p].lim=lim;return;}pushdown(p);if(l<=mid)mdf(l,r,lim,id,s,mid,lp);if(mid<r)mdf(l,r,lim,id,mid+1,t,rp);pushup(p);
}
void Merge(int l,int r,int lim,int id,int s=1,int t=1e5,int p=1){if(l<=s&&t<=r&&!st[p].typ){if(st[p].lim>=lim)combine(id,st[p].id);return;}pushdown(p);if(l<=mid)Merge(l,r,lim,id,s,mid,lp);if(mid<r)Merge(l,r,lim,id,mid+1,t,rp);pushup(p);
}
int solve(){sort(a+1,a+n+1);for(int i=1;i<=n;++i){Merge(a[i].x1,a[i].x2,a[i].y1,i);mdf(a[i].x1,a[i].x2,a[i].y2,i);}int ans=0;for(int i=1;i<=n;++i)if(find(i)==i)++ans;write(ans);return fw,0;
}
}int main(){freopen("jux.in","r",stdin);freopen("jux.out","w",stdout);n=read();iota(f+1,f+n+1,1);for(int i=1;i<=n;++i)a[i]={read(),read(),read(),read()};if(n>=40000)return zj::solve();for(int i=1;i<=n;++i)for(int j=i+1;j<=n;++j)if(check(a[i].x1,a[i].y1,a[i].x2,a[i].y2,a[j].x1,a[j].y1,a[j].x2,a[j].y2))combine(i,j);int ans=0;for(int i=1;i<=n;++i)ans+=(find(i)==i);write(ans);return fw,0;
}

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

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

相关文章

基于3peak 17串AFE芯片TPB76016-QP3R的电池BMS控制板方案

随着电动汽车、可再生能源存储设备以及便携式电子产品的普及,对高效、安全的电池管理系统(BMS)需求日益增加。17通道高精度电池管理产品—TPB76016,内置高精度基准,工作温度支持-40C to +125C,可广泛应用于动力电池、储能电池、以及其他消费类电池的BMS控制板。TPB76016-…

mysql登录遇到ERROR 1045问题解决方法

遇到 MySQL 登录时出现 ERROR 1045(访问被拒绝,用户名或密码错误),可以通过以下步骤来解决: 1. 确认用户名和密码检查用户名和密码:确认在连接数据库时输入的用户名和密码是否正确。 尝试在命令行中连接数据库,确认是否能成功登录:bashmysql -u your_username -p2. 重置…

网站提示连接数据库错误怎么解决

解决网站连接数据库错误通常需要检查以下几个方面:检查数据库连接参数确认数据库地址(hostname)、端口号、用户名和密码是否正确。 检查数据库名称是否正确。检查网络连接确保服务器与数据库之间的网络连通性正常。 如果是在云环境中,检查安全组设置或防火墙规则是否允许从…

验证码绕过爆破

验证码绕过爆破 图片验证码绕过 方法一、插件 xiapao 下载地址:https://github.com/smxiazi/NEW_xp_CAPTCHA/releases/tag/4.2 需要 python3.6 的环境来启动 sercer.py 服务,下载 python3.6 安装包,选择路径进行安装(不需要配置环境变量),然后再 pycharm 中打开文件,配置…

react 知识点汇总(非常全面)

React 是一个用于构建用户界面的 JavaScript 库,由 Facebook 开发并维护。它的核心理念是“组件化”,即将用户界面拆分为可重用的组件。 React 的组件通常使用 JSX(JavaScript XML)。JSX 是一种 JavaScript 语法扩展,允许开发者在 JavaScript 代码中编写类似 HTML 的结构。…

大核注意力机制

一、本文介绍 在这篇文章中,我们将讲解如何将LSKAttention大核注意力机制应用于YOLOv8,以实现显著的性能提升。首先,我们介绍LSKAttention机制的基本原理,它主要通过将深度卷积层的2D卷积核分解为水平和垂直1D卷积核,减少了计算复杂性和内存占用。接着,我们介绍将这一机制…

2024熵密杯wp

第一部分:初始谜题这一部分算是开胃菜,形式也更像平时见到的CTF题目,三个题目都是python加密的,做出其中任意一个就可以进入第二部分,也就是一个更类似真实情境的大型密码渗透系统。但每个初始谜题都是有分数的,所以就算开了第二部分也当然要接着做。每个题目也都有前三血…

2024高校网络安全管理运维赛 wp

0x00 前言本文是关于“2024高校网络安全管理运维赛”的详细题解,主要针对Web、Pwn、Re、Misc以及Algorithm等多方向题目的解题过程,包含但不限于钓鱼邮件识别、流量分析、SQLite文件解析、ssrf、xxe等等。如有错误,欢迎指正。0x01 Misc签到给了一个gif,直接在线分帧得到syn…

张量矩阵乘法分块乘法概述

张量矩阵乘法分块乘法概述 介绍一下矩阵计算相关的内容, 从最基本的算法,到Cutlass这些线性代数模版库, 特别是Layout代数相关的内容,再逐渐细化到一些硬件实现访存优化和一些算子融合。 6.3.1 GEMM概述 1. GEMM定义 对于一个矩阵乘法, 定义如下: (6-1)一个矩阵乘法定义,如…

Java与线程

Java与线程 1. 线程的实现 线程是比进程更轻量级的调度执行单位,线程的引人,可以把一个进程的资源分配和执行调度分开,各个线程既可以共享进程资源(内存地址、文件IO等),又可以独立调度。目前线程是Java里面进行处理器资源调度的最基本单位。 主流的操作系统都提供了线程实…