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. 整理k8s————k8s概念[一]

    前言 简单整理一下k8s. 正文 k8s 是基于容器的一套解决方案,那么解决了什么问题呢? 解决了分布式部署问题. k8s 特点: 轻量 开源 弹性伸缩:IPVS 知识图谱: 更多的看官网就好. 结 ...

  2. redis 简单整理——redis 的键管理[七]

    前言 简单整理一下redis的键管理. 正文 单个键管理 键重命名 rename key newkey 为了防止被强行rename,Redis提供了renamenx命令,确保只有newKey 不存在时 ...

  3. NodeJS安装cnpm

    介绍: NPM(Node Package Manager):Node的包管理器. CNPM(Chinese CPM):中国的NPM(国内使用,网速较快). 配置步骤 用npm安装cnpm npm in ...

  4. maven报错:501 HTTPS Required

    maven报错:501 HTTPS Required 简单来说,如果报错中出现http://repo1.maven.org/maven2/的字样的话,那么大概率就是Maven仓库的设置里的地址有问题, ...

  5. 数据库PolarDB开源之路该如何走?听听他们怎么说

    简介: 10月25日,由阿里云开发者社区.阿里云PolarDB开源社区.InfoQ联合举办的「开源人说」数据库PolarDB专场线下沙龙在杭州召开,5位阿里云数据库超级大咖.10位阿里云数据库开源生态 ...

  6. 璀璨智行:V2X车路协同智慧交通

    ​V2X车用无线通信技术是指车对外界的信息交换,作为未来智能交通运输系统的关键技术,璀璨智行潜心研究V2X技术,致力于V2X车路协同的落地,在智慧交通领域做出了卓越的贡献. 创业机会点 魏军博表示:& ...

  7. Serverless 时代下大规模微服务应用运维的最佳实践

    简介: 原来的微服务用户需要自建非常多的组件,包括 PaaS 微服务一些技术框架,运维 IaaS.K8s,还包括可观测组件等.SAE 针对这些方面都做了整体的解决方案,使用户只需要关注自己的业务系统, ...

  8. dotnet OpenXML 利用合并表格单元格在 PPT 文档插入不可见的额外版权信息

    本文告诉大家如何利用 Office 对于 OpenXML 支持的特性,在 PPT 的表格里面,通过合并单元格存放一些额外的信息,这些信息对用户来说是不可见的,但是进行拷贝表格等的时候,可以保存此信息内 ...

  9. SQL server 数据库巡检

    SELECT name FROM sysobjects where xtype='u' and name <>'XzryGzGrant' AND name LIKE 'XzryGzGran ...

  10. JS代码优化小技巧

    下面介绍一种JS代码优化的一个小技巧,通过动态加载引入js外部文件来提高网页加载速度 [基本优化] 将所有需要的<script>标签都放在</body>之前,确保脚本执行之前完 ...