noip模拟41
A. 你相信引力吗
很明显的单调栈的题,考场上没有想到平移最大值,而是想着复制一倍序列破环成链,然后发现最大值的部分特别难维护,而且耗费时间过长,只好牺牲时间复杂度加了个 \(map\) 去重。
首先把一个最大值放到最左边,这样除了最大值都不能跨过左端点走另一半的环进行匹配
然后维护单调不增栈,对于多个连续值维护当前是第几个,往后递推即可
过程中需要特判最大值防止算重
代码实现
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e7+5;
int n,a[maxn],mxpos,sta[maxn],f[maxn],tp;
long long ans;
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 main(){
n=read();
for(int i=1;i<=n;i++){
a[i+n]=a[i]=read();
if(a[i]>a[mxpos])mxpos=i;
}
for(int i=mxpos;i<mxpos+n;i++){
while(tp&&a[sta[tp]]<a[i])ans++,tp--;
if(a[sta[tp]]>a[i])ans++;
else ans+=f[sta[tp]]+(a[i]!=a[mxpos]);
sta[++tp]=i;
f[i]=(a[i]==a[sta[tp-1]])?f[sta[tp-1]]+1:1;
}
while(tp>2){
if(a[sta[tp]]==a[sta[2]])break;
tp--;
ans++;
}
cout<<ans;
return 0;
}
B. marshland
考虑网络流:
如果把格子黑白染色,那么一个有危险值的格子流量为 \(2\),但是费用流并不能控制其恰好为 \(2\),可能会出现流量为 \(1\) 但费用算入贡献的情况
那么可以按如下方法染色:
将棋盘染成类似上述三种颜色:
那么一种合法的方案一定由蓝到红再到黄(假定红色是危险的格子)
那么把红色格子拆点放在中间,连一条费用为危险值的边,蓝色作为左边点,原点向其连边,然后连向中间入点;黄色点放右边,从出点向其连边,然后连向汇点
注意这道题要求可行流,比起传统费用流来讲并不是有流就流,而是当前路径费用为正才流
C. party?
特产的选择方案比较奇怪,可以用网络流维护
这其实是一个二分图,左部点是 \(c\) 个人,每个人相当于拥有 \(k\) 的流量,然后每个人向其对应特产连边,特产流量为一
现在要计算满足满流的最大流量
根据 \(Hall\) 定理,二分图存在完美匹配当且仅当对于任意的 \(k\),左部任意 \(k\) 个点在右边的相邻点个数大于等于 \(k\)
由于 \(c\) 很小,直接枚举所有情况即可
对于统计一条路径上特产有哪些,可以开一个 \(bitset\),并用树剖维护
为了防止跳链浪费时间,树剖时对于完整的重链记录其所达特产,只在最后一部分线段树上查询
代码实现
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+5;
const int len=1005;
const int inf=0x3f3f3f3f;
int n,m,id[maxn],fa[maxn],x,dep[maxn],siz[maxn],son[maxn],re[maxn],tp[maxn],tot,num,pos[maxn],q,hd[maxn],cnt,c[maxn];
bitset<len>col[maxn],S[10];
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,to;
}edge[maxn];
void add(int u,int v){
edge[++cnt].nxt=hd[u];
edge[cnt].to=v;
hd[u]=cnt;
return ;
}
void dfs(int u){
siz[u]=1;
for(int i=hd[u];i;i=edge[i].nxt){
int v=edge[i].to;
dep[v]=dep[u]+1;
dfs(v);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
}
return ;
}
void dfs1(int u,int top){
tp[u]=top;
id[u]=++tot;
re[tot]=u;
if(u!=top)col[u]=col[fa[u]];
col[u].set(c[u]);//(1<<c[u]);
// cout<<u<<" "<<col[u]<<endl;
if(son[u])dfs1(son[u],top);
for(int i=hd[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==son[u])continue;
dfs1(v,v);
}
return ;
}
int lca(int x,int y){
while(tp[x]!=tp[y]){
if(dep[tp[x]]<dep[tp[y]])swap(x,y);
x=fa[tp[x]];
}
if(dep[x]<dep[y])swap(x,y);
return y;
}
struct Seg{
int l,r;
bitset<len>sc;
}t[maxn*4];
void update(int p){
t[p].sc|=t[p<<1].sc|t[p<<1|1].sc;
return ;
}
void build(int p,int l,int r){
t[p].l=l;
t[p].r=r;
if(l==r){
t[p].sc.set(c[re[l]]);
// t[p].sc|=(1<<c[re[l]]);
return ;
}
int mid=l+r>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
update(p);
return ;
}
bitset<len>ask(int p,int l,int r){
if(t[p].l>=l&&t[p].r<=r){
return t[p].sc;
}
int mid=t[p].l+t[p].r>>1;
bitset<len>ans;
if(l<=mid)ans=ask(p<<1,l,r);
if(r>mid)ans|=ask(p<<1|1,l,r);
return ans;
}
bitset<len>que(int x,int ed){
bitset<len>ans;
while(tp[x]!=tp[ed]){
ans|=col[x];
x=fa[tp[x]];
}
ans|=ask(1,id[ed],id[x]);
return ans;
}
int main(){
n=read();
m=read();
q=read();
for(int i=2;i<=n;i++){
fa[i]=read();
add(fa[i],i);
}
for(int i=1;i<=n;i++)c[i]=read();
dfs(1);
dfs1(1,1);
// for(int i=1;i<=n;i++)cout<<col[i]<<endl;
build(1,1,n);
for(int i=1;i<=q;i++){
num=read();
int d;
for(int j=1;j<=num;j++){
if(j==1)d=pos[j]=read();
else d=lca(d,pos[j]=read());
}
for(int j=1;j<=num;j++){
S[j]=que(pos[j],d);
// cout<<S[j]<<endl;
}
tot=inf;
for(int T=1;T<=(1<<num)-1;T++){
bitset<len>sum;
int pnum=0;
for(int j=1;j<=num;j++){
if(T&(1<<(j-1))){
pnum++;
sum|=S[j];
}
}
int x=sum.count();
tot=min(tot,x/pnum);
}
for(int j=1;j<=num;j++)S[j].reset();
printf("%d\n",tot*num);
}
return 0;
}
D. 半夜
首先题意转化为将 \(A\) 串复制一倍,没一个子串与 \(B\) 串的 \(LCS\)
暴力 \(n^3\)
复习一下 \(LCS\) 转移方程式为 \(f[i][j]=min(f[i-1][j],f[i][j-1],f[i-1][j-1]+1)\)
考虑优化:
设 \(f_{i,j,k}=LCS(S[i,j],T[1,k])\)
很明显有 \(f_{i-1,j,k}>f_{i-1,j-1,k}\) 可以推出 \(f_{i,j,k}>f_{i,j-1,k}\)
同理 \(f_{i,j,k}>f_{i,j,k-1}\) 推出 \(f_{i-1,j,k}>f_{i-1,j,k-1}\)
那么发现 \(dp\) 的转移有分解点 \(p_{j,k}\) 和 \(q_{j,k}\) 表示:
\]
那么推出下图(盗图 \(from\) 这篇博客):
这是 \(P<Q\) 且 \(S[j]!=T[k]\) 的情况,设 \(f_{i-1,j-1,k-1}=F\) 根据递推式推出前两行,取 \(max\) 推出第三行,发现 \(p_{j,k}=P\),\(q_{j,k}=Q\)
所有 \(S[j]=T[k]\) 的情况和这个相同
这是 \(P>Q\) 的情况,同理推出 \(p_{j,k}=Q\),\(q_{j,k}=P\)
这样两个分界点数组可以递推出来,然后实现 \(n^2\) 转移
代码实现
#include<bits/stdc++.h>
using namespace std;
const int maxn=4005;
char a[maxn],b[maxn];
int n,p[maxn][maxn],q[maxn][maxn],sum,ans;
int main(){
cin>>n;
scanf("%s",a+1);
scanf("%s",b+1);
for(int i=1;i<=n;i++)a[i+n]=a[i];
for(int i=1;i<=n*2;i++)p[i][0]=i+1,q[i][0]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=n*2;j++){
int P=p[j][i-1],Q=q[j-1][i];
if(a[j]!=b[i]&&P>Q){
p[j][i]=P,q[j][i]=Q;
}
else p[j][i]=Q,q[j][i]=P;
}
}
for(int i=1;i<=n;i++){
sum=0;
for(int j=i;j<n+i;j++){
if(i>=p[j][n])sum++;
}
ans=max(ans,sum);
}
cout<<ans;
return 0;
}
noip模拟41的更多相关文章
- [考试总结]noip模拟41
发现长时间鸽博客会导致 rp--,所以今天来补一补 这个题目其实不是很毒瘤,然而是非常毒瘤... 题目不说请就是非常非常的烦人 首先 \(T1\) 就整整有两个歧义的地方,也就是说我们一共有 \(4\ ...
- Noip模拟41 2021.8.16
T1 你相信引力吗 对于区间的大小关系问题,往往使用单调栈来解决 这道题的优弧和劣弧很烦,考虑将其等价的转化 由于所有的合法情况绕过的弧都不会经过最高的冰锥, 又因为环可以任意亲定起点,这样可以直接把 ...
- 2021.8.16考试总结[NOIP模拟41]
T1 你相信引力吗 肯定是单调栈维护.但存在重复值,还是个环,不好搞. 发现取区间时不会越过最大值,因此以最大值为断点将环断为序列.在栈里维护当前栈中有多少个与当前元素相等的元素,小分类讨论一下. 最 ...
- 【HHHOJ】NOIP模拟赛 玖 解题报告
点此进入比赛 得分: \(100+20+100=220\)(还不错) 排名: \(Rank\ 16\) \(Rating\):\(+20\) \(T1\):[HHHOJ263]「NOIP模拟赛 玖」三 ...
- NOIP模拟17.9.21
NOIP模拟17.9.21 3 58 145 201 161.5 样例输出21.6 数据规模及约定对于40% 的数据,N <= 20对于60% 的数据,N <= 1000对于100% 的数 ...
- NOIP模拟17.9.22
NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥
- NOIP模拟 17.8.18
NOIP模拟17.8.18 A.小菜一碟的背包[题目描述]Blice和阿强巴是好朋友但萌萌哒Blice不擅长数学,所以阿强巴给了她一些奶牛做练习阿强巴有 n头奶牛,每头奶牛每天可以产一定量的奶,同时也 ...
- NOIP 模拟4 T2
本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ...
- noip模拟32[好数学啊]
noip模拟32 solutions 真是无语子,又没上100,无奈死了 虽然我每次都觉得题很难,但是还是有好多上100的 战神都200多了,好生气啊啊啊 从题开始变难之后,我的时间分配越来越不均匀, ...
随机推荐
- 🔥 LeetCode 热题 HOT 100(21-30)
46. 全排列 思路:典型回溯法 class Solution { public List<List<Integer>> permute(int[] nums) { Linke ...
- Session与Cookie的原理以及使用小案例>从零开始学JAVA系列
目录 Session与Cookie的原理以及使用小案例 Cookie和Session所解决的问题 Session与Cookie的原理 Cookie的原理 Cookie的失效时机 小提示 Session ...
- 使用scrapy搭建大型爬虫系统
最近新项目准备启动,在开始前内容.词库这些都需要提前做好准备,所以就有了这篇文章.在开始动手,看了下行业核心词排在首页的站,发现内容都多得不要不要的,各种乱七八糟的频道.页面模板,心想,如果每个网站. ...
- Salesforce Integration 概览(七) Data Virtualization数据可视化
本篇参考:https://resources.docs.salesforce.com/sfdc/pdf/integration_patterns_and_practices.pdf Salesforc ...
- 批量删除gmail邮件
以删除tor.com发送的邮件为例说明. 首先点击邮件搜索框右边的三角,在"发件人"下面写上"tor.com": 点"搜索"按钮,看一下范围 ...
- MySQL-10-索引应用规范
建立索引的原则 SQL文件 sql文件下载链接: https://alnk-blog-pictures.oss-cn-shenzhen.aliyuncs.com/blog-pictures/world ...
- 题解 Defence
传送门 发现最少次数只和最左,最右及中间最长的全0段有关 本来想启发式合并,结果发现直接线段树合并搭配一个类似山海经的方法就可以过了 yysy,线段树单次合并的具体复杂度并不是 \(O(logn)\) ...
- wpf 实现印章,公章效果
能写一些特定外观的控件,是一个做界面开发的程序员的基础技能.基本上,不管你是做web,QT,MFC,Winform,WPF等等,如果自己看到一个比较好看的有趣的效果,能大致推断出它的实现方式并照猫画虎 ...
- Struts2之OGNL与ValueStack
时间:2017-1-12 12:02 --OGNL1.OGNL表达式是什么 OGNL的全称是Object-Graph Navigation Language的缩写,中文名是对象图导航语言,它是一 ...
- 使用Hugo和GitHub搭建博客
折腾了几天博客的框架终于搭建起来了.研究了一番之后,最终还是选择使用Hugo和GitHub来搭建博客.本文介绍了如何使用Hugo来搭建静态博客网站,并将其部署在GitHub上.使用https://&l ...