\(\color{white}{\mathbb{燕子来时青尚在,木荫遥看杏花菲,名之以:杏红}}\)


考场发现 \(t2\) 基本上是原题,\(t3\) 的套路见过,\(t4\) 像是并查集之类的算法,\(t1\) 是个扩欧,总之感觉今天的题非常可做

先写 \(t3\) 打完二进制分组,过了大样例,然后也没测时间也没对拍开始写 \(t2\),很快也过了大样例,然后推 \(t1\),像是个三分,打完稍调一下也过了大样例。

发现时间还有两个半小时,觉得良心出题人前三题都给了大样例,估计不用对拍了吧,于是开始想 \(t4\)

想了一个小时复杂度大概对了,半个小时码完,再写个暴力挂上对拍

发现还有将近一个小时,开始喝水上厕所(一度以为有生之年可以AK了)

最后考完发现两题都挂了,发现 \(t1\) 有个三分的细节写错了,\(t3\) 是位运算弄错了,总共挂了 135 的分……

还是得认真检查……


A. 数列

很明显是扩欧,然后要求一组解使得 \(abs(x)+abs(y)\) 最小,这个是单峰函数,写了个三分,但是左右 \(mid\) 写错了

更简单的做法是令 \(a < b\),那么求通解的时候 \(x\) 每次跨度大,\(y\) 跨度小,所以当 \(abs(x)\) 小的时候一定答案最小

代码实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e5+5;
int n,a,b,g,x,y,p[maxn],ans,xx,yy,ax,ay;
int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch)){
x=x*10+ch-48;
ch=getchar();
}
return x*f;
}
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
void exgcd(int a,int b){
if(!b){
x=1;
y=0;
return ;
}
exgcd(b,a%b);
int k=y;
y=x-a/b*y;
x=k;
return ;
}
int calc(int k){
return abs(xx+k*ax)+abs(yy-k*ay);
}
int solve(int val){
if(val%g){
puts("-1");
exit(0);
}
xx=x*val/g;
yy=y*val/g;
int l=-1e9,r=1e9,lastl=0,lastr=0,cnt=0;
while(l<r){
int lmid=(r-l+1)/3+l;
int rmid=l+r-lmid;
// cout<<l<<" "<<r<<" "<<lmid<<" "<<rmid<<endl;
if(calc(lmid)<calc(rmid))r=rmid;
else l=lmid;
if(l==lastl&&r==lastr)cnt++;
else lastl=l,lastr=r,cnt=0;
if(cnt>=2)break;
}
int mn=0x3f3f3f3f3f3f3f3f;
for(int i=l-1;i<=r+1;i++){
mn=min(mn,calc(i));
}
return mn;
}
signed main(){
// freopen("array.in","r",stdin);
// cout<<gcd(12,18);
n=read();
a=read();
b=read();
g=gcd(a,b);
// cout<<g<<endl;
exgcd(a,b);
ax=b/g;
ay=a/g;
// cout<<x<<" "<<y<<endl;
for(int i=1;i<=n;i++){
p[i]=read();
}
for(int i=1;i<=n;i++){
ans+=solve(abs(p[i]));
}
cout<<ans;
return 0;
}

B. 数对

类似与队长快跑,只不过这道题无序,按 \(min(a_i,b_i)\) 排序即可


C. 最小距离

二进制拆分写错+卡常挂成零分

一定注意 \((1<< pos ) \& x\) 的值不是 \(1\)!!!!

正解是记录每个点更新的源点或者次短路

代码实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=4e5+5;
const int maxm=1e6+5;
int n,m,x,y,w,hd[maxn],cnt,dis[maxn],a[maxn],k,ans[maxn],col[maxn];
bool vis[maxn];
int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch)){
x=x*10+ch-48;
ch=getchar();
}
return x*f;
}
struct Edge{
int nxt,from,to,val;
}edge[maxm];
void add(int u,int v,int w){
edge[++cnt].nxt=hd[u];
edge[cnt].to=v;
edge[cnt].val=w;
edge[cnt].from=u;
hd[u]=cnt;
return ;
}
struct Node{
int dis,id;
Node(){}
Node(int x,int y):dis(x),id(y){}
bool operator < (const Node & x)const{
return dis>x.dis;
}
};
priority_queue<Node>q;
void dij(){
memset(dis,0x3f,sizeof dis);
memset(vis,0,sizeof vis);
for(int i=1;i<=k;i++){
col[a[i]]=i;
q.push(Node(0,a[i]));
dis[a[i]]=0;
}
while(!q.empty()){
int u=q.top().id;
q.pop();
if(vis[u])continue;
vis[u]=true;
for(int i=hd[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(dis[v]>dis[u]+edge[i].val){
dis[v]=dis[u]+edge[i].val;
col[v]=col[u];
q.push(Node(dis[v],v));
}
}
}
return ;
}
signed main(){
// freopen("distance.in","r",stdin);
// freopen("my.out","w",stdout);
n=read();
m=read();
k=read();
memset(ans,0x3f,sizeof ans);
for(int i=1;i<=k;i++){
a[i]=read();
}
for(int i=1;i<=m;i++){
x=read();
y=read();
w=read();
add(x,y,w);
add(y,x,w);
}
dij();
for(int i=1;i<=cnt;i++){
if(col[edge[i].from]!=col[edge[i].to]){
ans[col[edge[i].from]]=min(ans[col[edge[i].from]],edge[i].val+dis[edge[i].from]+dis[edge[i].to]);
ans[col[edge[i].to]]=min(ans[col[edge[i].to]],edge[i].val+dis[edge[i].from]+dis[edge[i].to]);
}
}
for(int i=1;i<=k;i++){
printf("%lld ",ans[i]);
}
return 0;
}

D. 真相

这种题一看类似于图论

按照真假拆点建图后发现分成多个块,每个块的结尾都是 \(1\) 类节点

那么一种思路是枚举每个结尾点,统计所有与其相同的节点的真话总数,判断是否满足即可,这个可以预处理优化成 \(O(n)\)

代码实现
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int t,n,a[maxn],val[maxn],pos[maxn],val1[maxn],tot,w[maxn],sumtot,sum1[maxn],sum2[maxn];
bool vis[maxn];
char c[5];
int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch)){
x=x*10+ch-48;
ch=getchar();
}
return x*f;
}
void work(){
int op=0;
for(int i=1;i<=n;i++){
op^=a[i];
}
if(op==0)puts("consistent");
else puts("inconsistent");
return ;
}
void pre(){
for(int j=1;j<=tot;j++){
int p=pos[j];
int op=0;
while(!vis[p-1]){
p--;
if(!p)p=n;
if(vis[p])break;
op^=a[p];
val[j]+=(!op);
}
val[j]++;
p=pos[j],op=1;
while(!vis[p-1]){
p--;
if(!p)p=n;
if(vis[p])break;
op^=a[p];
val1[j]+=(!op);
// cout<<p<<" "<<a[p]<<" "<<op<<endl;
}
// cout<<val[j]<<" "<<val1[j]<<endl;
}
return ;
}
bool solve(){
for(int i=1;i<=n;i++){
sum1[w[i]]+=val[i];
sum2[w[i]]+=val1[i];
sumtot+=val1[i];
}
for(int i=1;i<=tot;i++){
int sum=sumtot-sum2[w[i]]+sum1[w[i]];
if(sum==w[i])return true;
}
int sum=0;
for(int i=1;i<=tot;i++){
sum+=val1[i];
}
for(int i=1;i<=tot;i++){
if(sum==w[i])return false;
}
return true;
}
void init(){
for(int i=1;i<=n;i++){
a[i]=vis[i]=val[i]=val1[i]=sum1[i]=w[i]=sum2[i]=0;
}
tot=sumtot=0;
return ;
}
int main(){
// freopen("shuju.in","r",stdin);
// freopen("my1.out","w",stdout);
t=read();
while(t--){
init();
n=read();
for(int i=1;i<=n;i++){
scanf("%s",c+1);
if(c[1]=='$')pos[++tot]=i,vis[i]=true,w[tot]=read();
else if(c[1]=='-')a[i]=1;
else a[i]=0;
}
if(!tot){
work();
continue;
}
pre();
if(solve())puts("consistent");
else puts("inconsistent");
}
return 0;
}

\(\color{white}{\mathbb{花褪残红青杏小,燕子来时,绿水人家绕。}}\)

noip模拟37的更多相关文章

  1. Noip模拟37 2021.8.12

    T1 数列 真是考场上不是数学的乱推柿子,想定理,是数学的没想出来.. 比较悲伤... 列柿子不用动脑子,就是没有想出来$EXgcd$解不定方程,淦.. 解处一组解后利用比较显然的性质: $x+\fr ...

  2. 2021.8.12考试总结[NOIP模拟37]

    T1 数列 考场上切掉的简单题. $a$,$b$与数列中数的正负值对答案无关.全当作正数计算即可. $exgcd$解未知数系数为$a$,$b$,加和为$gcd(a,b)$的不定方程组,再枚举每个数.如 ...

  3. NOIP模拟 37

    啊哈这次没什么智障低错丢rank什么的托词了STO 发现好像110我就拿满了.. 水平不行..只会简单题qaq T1 可以树上启发式合并水过(普通分治也行) T2 我连那么显然的 一劳永逸的容斥都没想 ...

  4. 812考试总结(NOIP模拟37)[数列·数对·最小距离·真相]

    前言 考得挺憋屈的... 先是搞了两个半小时的 T1 后来发现假了,又没多想跳了.. 然后一看 T2 这不是队长快跑嘛... 先是根据自己的想法打了一遍(考完之后发现是对的..) 然后回想了一下之前的 ...

  5. NOIP模拟17.9.22

    NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥

  6. NOIP 模拟4 T2

    本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ...

  7. noip模拟32[好数学啊]

    noip模拟32 solutions 真是无语子,又没上100,无奈死了 虽然我每次都觉得题很难,但是还是有好多上100的 战神都200多了,好生气啊啊啊 从题开始变难之后,我的时间分配越来越不均匀, ...

  8. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  9. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

随机推荐

  1. mysql查询拥有某个字段的所有表

    前言:最近遇到一个需求,需要给一个数据库所有的表添加一个字段,但是一些后创建的表已经有了这个字段,所以引发了下文. *注释 columnName 字段名   dbName 数据库名 #查询指定库拥有某 ...

  2. 根据随身固态U盘卷标搜索U盘盘符并打开文件的批处理脚本.bat 徐晓亮 595076941@qq.com 2019年12月19日6点50分

    @Echo offRem 根据随身固态U盘卷标搜索U盘盘符并打开文件的批处理脚本.batRem 徐晓亮 595076941@qq.com 2019年12月19日6点50分 Rem 此批处理脚本源代码的 ...

  3. Linux下-LNMP环境搭建博客网站(全过程)

    通常我们所说的LNMP是指一个网站基本的组织框架,即Linux系统支持,Nginx静态服务,Mysql数据库支持以及PHP动态编程语言支持.目前Mysql数据库被Oracle数据库分析公司收购,其创始 ...

  4. linux中的防火墙netfilter iptables

    目录 一.Linux防火墙基础 1.1 ptables的表.链结构 1.2 数据包控制的匹配流程 二.编写防火墙规则 1.iptables的安装 2.1 基本语法.控制类型 一般在生产环境中设置网络型 ...

  5. Wireshark过滤器详解

    Wireshark过滤器详解 1.Wireshark主要提供两种主要的过滤器 捕获过滤器:当进行数据包捕获时,只有那些满足给定的包含/排除表达式的数据包会被捕获 显示过滤器:该过滤器根据指定的表达式用 ...

  6. XCTF-Web进阶-upload1

    显然是让我们上传文件,思路当然是上传一个木马文件,然后通过蚁剑连接查看目录获取flag. 但是当我们想要上传php文件的时候会出现弹窗,并且连"上传"按钮都被禁用了. ext = ...

  7. 智能合约审计-不安全的delegatecall

    简介 当合约A以delegatecall方式调用时, 相当于将外部合约B的func()代码复制过来 (其函数中涉及的变量或函数都需要在本地存在), 在合约A上下文空间中执行. 合约 pragma so ...

  8. Windows API 进程相关笔记

    0. 前言 最近做了一个进程信息相关的项目,整理了一下自己做项目时的笔记,分享给大家 1. 相关概念 1.1 HANDLE 概念 HANDLE(句柄)是Windows操作系统中的一个概念. 在Wind ...

  9. OpenStack中VNC协议实现多屏共享(多屏不踢访问)

    OpenStack中VNC协议实现多屏共享 by 无若   libvirt设置基本说明:   <devices> <graphics type='sdl' display=':0.0 ...

  10. [JAVA]关于excel的jxl包的操作-创建sheet

    前言 最近玩的游戏需要记录数据, 手打excel太麻烦了 于是就学了学java的jxl操作.本来记录在有道云笔记就可以的,由于乐于分享的精神 就在博客园造了个号, 之前自己本来有做个人的网站的,奈何网 ...