T1 ladice

解题思路

我们把一个物品看做 \(A_i\) 与 \(B_i\) 之间的连边。

那么如果加入这条边之后联通块中有超过两个环或者两个环就是不合法的,也就是合法的状态只能是一个基环树和树的森林这样一个形态。

直接并茶几判断连通性,标记一下当前的联通块中是否有环就好了。

code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"RP++"<<endl
using namespace std;
inline int read()
{
int x=0,f=1; char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=3e5+10;
int n,m,fa[N];
bool vis[N];
int find(int x)
{
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
#undef int
int main()
{
#define int register long long
freopen("ladice.in","r",stdin); freopen("ladice.out","w",stdout);
m=read(); n=read();
for(int i=1;i<=n;i++) fa[i]=i;
while(m--)
{
int x,y; x=find(read()); y=find(read());
if(x==y&&vis[x]){printf("SMECE\n");continue;}
if(x!=y&&vis[x]&&vis[y]){printf("SMECE\n");continue;}
if(x==y) vis[x]=true;
else fa[x]=y,vis[y]|=vis[x];
printf("LADICA\n");
}
return 0;
}

T2 card

解题思路

主要是 DP 方程的含义比较难想,\(f_{i,j,k,0/1}\) 表示当前栈中自栈顶到栈底前三个标号是 \(i,j,k\) 。

并且当前可以是否可以选择第一个或者第三个,对于一种已经确定的状态而言,设栈的前三个元素是 \(x,y,z\) ,那么\(z\) 前面的所有牌除了 \(x,y\) 以外一定都已经被取走了,直接前缀和计算即可。

code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"RP++"<<endl
using namespace std;
inline int read()
{
int x=0,f=1; char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=510,INF=1e18;
int n,ans,pre[N];
bool f[N][N][N][2];
struct Node{int a,b,val;}s[N];
bool judge(int x,int y){return s[x].a==s[y].a||s[x].b==s[y].b;}
#undef int
int main()
{
#define int register long long
freopen("card.in","r",stdin); freopen("card.out","w",stdout);
n=read();
for(int i=1;i<=n;i++)
s[i].a=read(),s[i].b=read(),
s[i].val=read(),pre[i]=pre[i-1]+s[i].val;
f[1][2][3][0]=true; f[1][2][3][1]=true;
f[2][3][4][0]=judge(1,2); f[1][2][4][1]=judge(3,4);
f[1][2][4][0]=judge(1,3); f[2][3][4][1]=judge(1,4);
for(int i=1;i<=n+5;i++)
for(int j=i+1;j<=n+5;j++)
for(int k=j+1;k<=n+5;k++)
{
if(f[i][j][k][0])
{
f[j][k][k+1][0]|=judge(i,j);
f[j][k][k+1][1]|=judge(i,k+1);
ans=max(ans,pre[min(k-1,n)]-s[j].val);
}
if(f[i][j][k][1])
{
f[i][j][k+1][0]|=judge(k,i);
f[i][j][k+1][1]|=judge(k,k+1);
ans=max(ans,pre[min(k,n)]-s[i].val-s[j].val);
}
}
printf("%lld",ans);
return 0;
}

T3 dojave

解题思路

假设当前选中子串的 \(xor\) 和为 \(Sum\) ,设 \(t=2^M-1\) ,\(d=t\otimes Sum\),我们称 \((x,y)\) 配对当且仅当 \(x\otimes y=Sum\otimes t\) 。

先放一下结论:

不合法的序列一定是长度为 4 的倍数并且序列中的元素可以两两进行配对。

首先序列中元素如果不是两两配对的这个序列一定是合法的。

奇数的情况一定合法,因为至少会存在一个在序列中的 \(x\) 在序列外有一个 \(y\) 与之配对。

对于偶数序列元素两两配对的的情况只有 长度为 4 的倍数才是不合法的。

我们以长度为 6 的为例,那么 \(Sum=d\otimes d \otimes d\) 但是显然 \(d\neq Sum\) ,于是这种情况不存在,其他二的倍数可以类推。

然后代码实现的话可以整一个异或前缀和+桶判断,也可以给两个异或为 \(t\) 的附上两个绝对值相同但是符号不同的数做一遍无序 Hash 。

code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"RP++"<<endl
using namespace std;
inline int read()
{
int x=0,f=1; char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
mt19937 rnd(1ull*time(0)*clock()*rnd()*rand());
const int N=(1<<20)+10;
const ull base=13331; ull t;
int n,m,ans,s[N],pre[N][2],pos[N];
unordered_map<ull,int> cnt[4];
ull id(int x,int y){return 1ull*x*base+y;}
#undef int
int main()
{
#define int long long
freopen("dojave.in","r",stdin); freopen("dojave.out","w",stdout);
m=read(); n=1<<m; ans=n*(n+1)/2;
if(m==1) printf("2"),exit(0); cnt[0].insert(make_pair(0,1));
for(int i=1;i<=n;i++) s[i]=read(),pos[s[i]]=i;
for(int k=0;k<=1;k++) for(int i=1;i<=n;i++) pre[i][k]=pre[pos[(n-1)^s[i]]][k]=rnd()|(rnd()<<15);
for(int k=0;k<=1;k++) for(int i=1;i<=n;i++) pre[i][k]^=pre[i-1][k];
for(int i=1;i<=n;i++) cnt[i%4].insert(make_pair(id(pre[i][0],pre[i][1]),0));
for(int i=1;i<=n;i++) t=id(pre[i][0],pre[i][1]),ans-=cnt[i%4].find(t)->second,cnt[i%4][t]++;
printf("%lld",ans);
return 0;
}

T4 drop

解题思路

求水不是特别好求,我们考虑求出 水+柱子 的体积最后再减去柱子的体积。

发现对于最高的柱子在中间的情况其实可以把最高柱子一侧的柱子平移到另一边,其实是一样的,类似于下图的这种情况:

由于我们计算的是 水+柱子 的体积,因此对于一个位置 \(pos\) 它有意义当且仅当它比他左边或者右边的柱子高。

同时根据上图,我们可以发现其实所有柱子和水的体积之和就是两个次高柱子的高度。

那么我们可以先将所有的柱子从小到大枚举,每次插入一个次小值,然后枚举插入这个柱子后可以构成几个 水+柱子 的体积是这样高度的格子。

一个类似于背包的东西直接 bitset 维护。

code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"RP++"<<endl
using namespace std;
inline int read()
{
int x=0,f=1; char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=5e2+10,M=25e3+10;
int n,cnt,sum,s[N];
bitset<M> bit[N],ans;
#undef int
int main()
{
#define int long long
freopen("drop.in","r",stdin); freopen("drop.out","w",stdout);
n=read(); for(int i=1;i<=n;i++) s[i]=read(),sum+=s[i]; ans[sum]=true;
sort(s+1,s+n+1,greater<int>()); bit[1][s[1]]=true;
for(int i=2;i<=n;i++) bit[i]|=bit[i-1]<<s[2];
for(int i=3;i<=n;i++) if(s[i]!=s[i-1])
{for(int j=i;j<=n;j++) bit[j]|=bit[j-1]<<s[i];ans|=bit[n];}
for(int i=sum;i<=M-10;i++) if(ans[i]) printf("%lld ",i-sum);
return 0;
}

NOIP模拟101(多校33)的更多相关文章

  1. NOIP模拟83(多校16)

    前言 CSP之后第一次模拟赛,感觉考的一般. 不得不吐槽多校联测 OJ 上的评测机是真的慢... T1 树上的数 解题思路 感觉自己思维有些固化了,一看题目就感觉是线段树. 考完之后才想起来这玩意直接 ...

  2. NOIP模拟92(多校25)

    前言 所以说这次是 HZOI 多校联测巅峰????(题目,数据过水??) T1 石子合并 解题思路 签到题. 发现我们可以给每个数字附一个正负号,每个数字的贡献就是它本身乘上这个符号. 发现至少应该有 ...

  3. NOIP模拟84(多校17)

    T1 宝藏 解题思路 考场上一眼出 \(nlog^2\) 做法,然后没看见是 1s 3e5 的数据,我竟然以为自己切了?? 考完之后尝试着把二分改为指针的移动,然后就过了??或许是数据水吧,感觉自己的 ...

  4. NOIP模拟85(多校18)

    前言 好像每个题目背景所描述的人都是某部番里的角色,热切好像都挺惨的(情感上的惨). 然后我只知道 T1 的莓,确实挺惨... T1 莓良心 解题思路 首先答案只与 \(w\) 的和有关系,于是问题就 ...

  5. NOIP模拟86(多校19)

    T1 特殊字符串 解题思路 \(f_{i,j}\) 表示前 \(i\) 个字符中结尾为 \(j\) 的最大贡献. 转移枚举当前位置于之前位置结尾的组合加上贡献即可. 对于边界问题,容易发现选择 1 一 ...

  6. NOIP模拟88(多校21)

    前言 对于这套题的总体感觉就是难,然后就是自己很菜... 对于 T1 考试时只会一个最垃圾的背包,考完之后对于思路这一块也不是很顺利,大概这就是薄弱的地方吧. 然后 T2 是比较简单的一道题了,但是考 ...

  7. NOIP模拟96(多校29)

    T1 子集和 解题思路 大概是一个退背包的大白板,然而我考场上想复杂了,竟然还用到了组合数. 但是大概意思是一样的,有数的最小值一定是一个在 \(a\) 数组中存在的数字. 那么我们想办法除去它对应的 ...

  8. NOIP模拟99(多校31)

    T1 法阵 解题思路 原题3100,张口放 T1(出题人原话) 思维题,合法的情况其实就是上下两个梯形拼起来的样子. 他们的边界都是在 \(i\) 轴上面,但是不能相交. 于是我们可以尝试两者相交的纵 ...

  9. noip模拟33[进阶啦啦啦]

    noip模拟33 solutions 不知道该咋说,这场考试其实是我这三四场以来最最最最最顺心的一场了 为啥呢?因为我这回思考有很多结果,得到了脑袋的回复 就是你想了半个小时就有了一点点头绪,那感觉就 ...

  10. noip模拟33

    \(\color{white}{\mathbb{失足而坠千里,翻覆而没百足,名之以:深渊}}\) 这场考试的时间分配非常不科学 开题试图想 \(t1\) 正解,一个半小时后还是只有暴力,特别惊慌失措 ...

随机推荐

  1. 抓包整理————wireshark DNS 演练[三]

    前言 简单整理一些wireshark dns 演练. 正文 简单介绍一下什么是dns. 这个其实可以百度一下哈,其实就是将域名转换为ip. 然后查询过程是这样的: 根域名服务器 权威服务器 dns 被 ...

  2. MMDeploy部署实战系列【第四章】:onnx,tensorrt模型推理

    MMDeploy部署实战系列[第四章]:onnx,tensorrt模型推理 这个系列是一个随笔,是我走过的一些路,有些地方可能不太完善.如果有那个地方没看懂,评论区问就可以,我给补充. 目录: 0️⃣ ...

  3. 鸿蒙HarmonyOS实战-ArkUI组件(Image)

    一.Image 在HarmonyOS中,Image组件是用于显示图像文件的UI组件.它可以显示本地图像文件或远程URL地址的图像文件.Image组件的实现方式比较简单,只需提供图像文件路径或URL地址 ...

  4. Linux下的权限(角色,文件权限)

    目录 1.什么是权限 2.文件类型及权限 ①Linux文件类型: ②剩余9个字符对应的含义: ③文件权限值的表示方法(进制法) 3.如何操作权限 3.1改变权限的命令操作 chmod #change ...

  5. 力扣1662(java&python)-检查两个字符串数组是否相等(简单)

    题目: 给你两个字符串数组 word1 和 word2 .如果两个数组表示的字符串相同,返回 true :否则,返回 false . 数组表示的字符串 是由数组中的所有元素 按顺序 连接形成的字符串. ...

  6. 牛客网-SQL专项训练25

    ①批处理是指包含一条或多条T-SQL语句的语句组,下列选项中,关于批处理的规则描述正确的是(B) 解析: A选项:不能定义一个check约束后,立即在同一个批处理中使用: C选项:Create def ...

  7. 云原生时代如何用 Prometheus 实现性能压测可观测-Metrics 篇

    ​简介:可观测性包括 Metrics.Traces.Logs3 个维度.可观测能力帮助我们在复杂的分布式系统中快速排查.定位问题,是分布式系统中必不可少的运维工具. 作者:拂衣 什么是性能压测可观测 ...

  8. 如何从 0 到 1 开发 PyFlink API 作业

    简介: 以 Flink 1.12 为例,介绍如何使用 Python 语言,通过 PyFlink API 来开发 Flink 作业. Apache Flink 作为当前最流行的流批统一的计算引擎,在实时 ...

  9. 阿里云 EDAS 3.0 助力唱鸭提升微服务幸福感

    简介: EDAS 3.0 提供的微服务治理,很好的支持了唱鸭 APP 实现微服务应用的发布.监控.管理等日常业务场景.作为运维侧的重要平台和开框架的提供者,EDAS 3.0 帮助用户可以更专注业务.微 ...

  10. 【深度】阿里巴巴万级规模 K8s 集群全局高可用体系之美

    简介: 台湾作家林清玄在接受记者采访的时候,如此评价自己 30 多年写作生涯:"第一个十年我才华横溢,'贼光闪现',令周边黯然失色:第二个十年,我终于'宝光现形',不再去抢风头,反而与身边的 ...