模拟赛20200228(yyq)【右链+dfs序,子树管辖,聚集水流问题】
T1:管理
对998244853998244{\color{red}{8}}53998244853取模
题解:
知道至少要多少还是不好做,能不能把它转化成暂时只计算这么多个呢?
是可以的,因为在一棵树的右链上接一棵子树不会改变原树的dfs序的,所以我们只需要记下右链的长度即可;因为限制关系形成了树形结构,记siz[i]siz[i]siz[i]为iii至少需要管辖的人数,记f[i][j]f[i][j]f[i][j]表示[i,i+siz[i]−1][i,i+siz[i]-1][i,i+siz[i]−1]形成的树的右链长度为jjj的方案数,转移就按顺序将iii在限制树中的子树合并到iii上即可,由f[i][x∼siz[i]]∗f[j][y]→f[i][x+y]f[i][x\sim siz[i]]*f[j][y]\to f[i][x+y]f[i][x∼siz[i]]∗f[j][y]→f[i][x+y],记录一下后缀和,就是O(n2)O(n^2)O(n2)的。
Code:
#include<bits/stdc++.h>
#define maxn 4505
using namespace std;
const int mod = 998244853;
int n,a[maxn],fa[maxn],siz[maxn],sum[maxn],f[maxn][maxn];
int main()
{freopen("administration.in","r",stdin);freopen("administration.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&a[i]);a[1]=n;for(int i=n;i>=1;i--){if((a[i]+=i-1)>n) return puts("0"),0;fa[i]=i,a[i]=a[fa[a[i]]];//fa[i]:i在哪个限制的范围中,a[i]:i的限制范围f[i][siz[i]=1]=1;for(int j=i+1;j<=a[i];j=a[j]+1){sum[siz[i]+1]=0;for(int k=siz[i];k>=1;k--) sum[k]=(sum[k+1]+f[i][k])%mod,f[i][k]=0;for(int x=1;x<=siz[i];x++)for(int y=1;y<=siz[j];y++)f[i][x+y]=(f[i][x+y]+1ll*sum[x]*f[j][y])%mod;siz[i]+=siz[j];}for(int j=i+1;j<=a[i];j++) fa[j]=i;}int ans=0;for(int i=1;i<=n;i++) ans=(ans+f[1][i])%mod;printf("%d\n",ans);
}
T2:
题解:
这种水流题要是陷入模拟的怪圈之中就会被各种特殊情况恶心致死。
正确的姿势应该是枚举最后水的范围[L,R][L,R][L,R],然后硬把所有的水都聚集到这里来。值得注意的是如果考虑L−1L-1L−1和R+1R+1R+1,那么水的高度可能并不具有单调性,我们可先不考虑两边算出水的高度,然后再与两边比较,如果高了就将[L,R][L,R][L,R]挖低。
记f(l,r)f(l,r)f(l,r)为水的区间为[l,r][l,r][l,r]时水的高度,那么显然f(l,r)≥f(l,r+1)f(l,r)\ge f(l,r+1)f(l,r)≥f(l,r+1),考虑固定lll,扫描rrr,那么就可以令高度从1000在整数范围往下递减,算答案的时候根据在水下的块数补上小数部分的答案。复杂度O(n2)O(n^2)O(n2)。
Code:
#include<bits/stdc++.h>
#define maxn 5005
using namespace std;
int T,n,lp,rp,ml[maxn],mr[maxn],sl[maxn],sr[maxn],S[maxn],a[maxn],w[maxn],cnt[1005];
int main()
{freopen("exploration.in","r",stdin);freopen("exploration.out","w",stdout);scanf("%d",&T);while(T--){scanf("%d",&n),a[0]=a[n+1]=1e9,w[0]=0;for(int i=1;i<=n;i++) scanf("%d",&a[i]),S[i]=S[i-1]+a[i];for(int i=1;i<=n;i++) scanf("%d",&w[i]),w[0]+=w[i];for(int i=1;i<=n;i++)if(!w[i]) ml[i]=sl[i]=0;else{lp=i,ml[i]=a[i],sl[i]=0;for(int j=i+1;j<=n;j++) ml[j]=min(ml[j-1],a[j]);for(int j=i+1;j<=n;j++) sl[j]=sl[j-1]+a[j]-ml[j];break;}for(int i=n;i>=1;i--)if(!w[i]) mr[i]=sr[i]=0;else{rp=i,mr[i]=a[i],sr[i]=0;for(int j=i-1;j>=1;j--) mr[j]=min(mr[j+1],a[j]);for(int j=i-1;j>=1;j--) sr[j]=sr[j+1]+a[j]-mr[j];break;}double ans=1e9;for(int l=1;l<=n;l++){memset(cnt,0,sizeof cnt);int h=1000,down=0,cd=0;for(int r=l;r<=n;r++){if(a[r]<=h){down+=h-a[r],cnt[a[r]]++,cd++;while(down>w[0]) down-=cd-=cnt[h--];}double x=h+1.0*(w[0]-down)/cd;double res=S[r]-S[l-1]-x*(r-l+1)+w[0];int lh=a[l-1],rh=a[r+1];if(lp<l) lh=ml[l-1],res+=sl[l-1];if(r<rp) rh=mr[r+1],res+=sr[r+1];if(x>min(lh,rh)) res+=(x-min(lh,rh))*(r-l+1);ans=min(ans,res);}}printf("%.5f\n",ans);}
}
T3:谈判
n≤500,wi≤106n≤500,w_i≤10^6n≤500,wi≤106
题解:
(原题CF1061E)
两棵树,集合限制,带权 ⇒\Rarr⇒ 费用流。
SSS向第一棵树的限制点连容量为b[i]−∑j是j到i路径上的第一个限制点b[j]b[i]-\sum_{j是j到i路径上的第一个限制点} b[j]b[i]−∑j是j到i路径上的第一个限制点b[j],费用为0的边。
第二棵树的限制点向TTT连容量为b[i]−∑j是j到i路径上的第一个限制点b[j]b[i]-\sum_{j是j到i路径上的第一个限制点} b[j]b[i]−∑j是j到i路径上的第一个限制点b[j],费用为0的边。
设每个城市在第一棵树中被xxx管辖,在第二棵树中被yyy管辖,则xxx向yyy连容量为1,费用为w[i]w[i]w[i]的边。
跑最大费用最大流即可。
注意b[i]b[i]b[i]可以为0,所以初值设为-1.
Code:
#include<bits/stdc++.h>
#define maxn 1005
#define maxm 5005
using namespace std;
const int inf = 0x3f3f3f3f;
int n,S,T,X,Y,a[maxn];
int fir[maxn],nxt[maxm],to[maxm],c[maxm],w[maxm],tot=1;
inline void line(int x,int y,int z,int v){nxt[++tot]=fir[x],fir[x]=tot,to[tot]=y,c[tot]=z,w[tot]=v;nxt[++tot]=fir[y],fir[y]=tot,to[tot]=x,c[tot]=0,w[tot]=-v;
}
void Fail(){puts("-1");exit(0);}
struct Tree{vector<int>G[maxn];int b[maxn],bel[maxn]; bool flg;void link(int x,int y){G[x].push_back(y),G[y].push_back(x);}int dfs(int u,int ff,int top){int sum=0; bel[u]=top;for(int i=0,lim=G[u].size(),v;i<lim;i++) if((v=G[u][i])!=ff)sum+=dfs(v,u,b[v]?v:top);if(b[u]){if(b[u]<sum) Fail();if(!flg) line(S,u,b[u]-sum,0);else line(u+n,T,b[u]-sum,0);return b[u];}return sum;}
}T1,T2;
int pre[maxn],E[maxn],dis[maxn]; bool inq[maxn];
queue<int>q;
bool SPFA(){memset(dis,-0x3f,(T+1)<<2);dis[S]=0,q.push(S),pre[T]=-1;while(!q.empty()){int u=q.front(); q.pop(),inq[u]=0;for(int i=fir[u],v;i;i=nxt[i]) if(c[i]&&dis[v=to[i]]<dis[u]+w[i]){dis[v]=dis[u]+w[i],pre[v]=u,E[v]=i; if(!inq[v]) inq[v]=1,q.push(v);}}return ~pre[T];
}
int Costflow(){int ans=0,flow=0;while(SPFA()){int mn=inf;for(int i=T;i!=S;i=pre[i]) mn=min(mn,c[E[i]]);for(int i=T;i!=S;i=pre[i]) c[E[i]]-=mn,c[E[i]^1]+=mn;ans+=dis[T]*mn,flow+=mn;}if(flow!=T1.b[X]) Fail();return ans;
}
int main()
{freopen("negotiation.in","r",stdin);freopen("negotiation.out","w",stdout);int x,y,m;scanf("%d%d%d",&n,&X,&Y),S=0,T=2*n+1; for(int i=1;i<=n;i++) scanf("%d",&a[i]);for(int i=1;i<n;i++) scanf("%d%d",&x,&y),T1.link(x,y);for(int i=1;i<n;i++) scanf("%d%d",&x,&y),T2.link(x,y);scanf("%d",&m);while(m--) scanf("%d%d",&x,&y),T1.b[x]=y;scanf("%d",&m);while(m--) scanf("%d%d",&x,&y),T2.b[x]=y;if(T1.b[X]!=T2.b[Y]) Fail();T1.dfs(X,0,X),T2.flg=1,T2.dfs(Y,0,Y);for(int i=1;i<=n;i++) line(T1.bel[i],T2.bel[i]+n,1,a[i]);printf("%d\n",Costflow());
}
模拟赛20200228(yyq)【右链+dfs序,子树管辖,聚集水流问题】相关推荐
- 计蒜客 A组模拟赛 青出于蓝胜于蓝(dfs序,树状数组)
题意:中文 武当派一共有 n 人,门派内 n 人按照武功高低进行排名,武功最高的人排名第 1,次高的人排名第 2,... 武功最低的人排名第 n.现在我们用武功的排名来给每个人标号,除了祖师爷,每个人 ...
- Java 第十一届 蓝桥杯 省模拟赛 小明植树(DFS)
小明植树 题目 问题描述 小明和朋友们一起去郊外植树,他们带了一些在自己实验室精心研究出的小树苗. 小明和朋友们一共有 n 个人,他们经过精心挑选,在一块空地上每个人挑选了一个适合植树的位置,总共 n ...
- [NOIP10.6模拟赛]2.equation题解--DFS序+线段树
题目链接: 咕 闲扯: 终于在集训中敲出正解(虽然与正解不完全相同),开心QAQ 首先比较巧,这题是\(Ebola\)出的一场模拟赛的一道题的树上强化版,当时还口胡出了那题的题解 然而考场上只得了86 ...
- 2018蓝桥杯模拟赛·青出于蓝而胜于蓝 DFS序+树状数组
武当派一共有 nnn 人,门派内 nnn 人按照武功高低进行排名,武功最高的人排名第 111,次高的人排名第 222,... 武功最低的人排名第 nnn.现在我们用武功的排名来给每个人标号,除了祖师爷 ...
- 瓜瓜的时空旅行,第三次模拟赛,dfs序+线段树维护最小值
题目描述 西瓜们生活在编号 1⋯n 的 n个平行时空中,2n−2 台时光机将这些平行时空联系在一起.一台时光机有 3个整数参数 u,v,t 表示从时空 u 可以花费 t 的时间穿梭到时空 v.为了确保 ...
- 树链剖分 or 根号分治 + dfs序 + 树状数组 ---- CF1254 D. Tree Queries
题目链接 题目大意: 问题转化: 很容易发现:假设修改的节点是vvv. 1.vvv的子树sonvson_vsonv直接加上(n−size[sonv])n×d\frac{(n-size[son_v]) ...
- bzoj3252攻略(线段树+dfs序)或者(树链剖分+dfs)
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1341 Solved: 642 [Submit][Status][Discuss] ...
- 简单dfs序 + 树链剖分
树链剖分 DFS序 先来讲一讲DFS序是什么东西,直接上图,方便理解. 估计巨巨们应该知道了DFS序的两个重要的东西,in,outin,outin,out数组. ininin数组就是这个点进入DFS的 ...
- 【noip模拟赛4】Matrix67的派对 暴力dfs
[noip模拟赛4]Matrix67的派对 描述 Matrix67发现身高接近的人似乎更合得来.Matrix67举办的派对共有N(1<=N<=10)个人参加,Matrix67需要把他们安排 ...
最新文章
- 常用的数据统计Sql 总结(转)
- HighNewTech:【2019WAIC世界人工智能大会】上海正式开幕——现场精彩时刻
- 转我们经理的一篇文章,业务流程实现的讨论,希望大家集思广议。
- Modelsim仿真tcl脚本与wave.do文件
- python 自动上报json信息_python接口自动化5-Json数据处理
- 简洁版即时聊天---I/O多路复用使用
- java 接口初始化_Java类的初始化 | 学步园
- 前端开发 html常用标签 0229
- JavaScript常用工具Date对象和Math介绍介绍
- 教育|仝卓高考舞弊案细节曝光:为“恢复高考成绩”已起诉1年多
- oracle预备份,oracle自动备份
- Oracle11g导出空表解决方法
- 哈工大中文分词系统LTP(pyltp)学习笔记
- 数字化转型背景下的“新IT职业教育” | 职业教育系列报告(四)
- iOS系列—wakeup in XNU
- Hark的数据结构与算法练习之珠排序
- 嵌入式 linux 应用 go 语言开发(开篇,缘起)
- 程序人生丨25岁毕业,月薪1万
- 计算机手速如何学,拼不过手速的你,来学学这些操作
- PyGame每日一练——五子棋小游戏
热门文章
- 最新92kaifa开发的帝国cms7.5美nv主播视频网站源码 自适应手机端
- ESP32 ADF windows开发环境搭建 适配ADF到ESP32A1S
- Firebase token认证 “kid“ invalid, unable to lookup correct key
- 监听器和监听器过滤器常见应用GUl中理解
- FBI 打击全球 DDoS 出租市场
- java resolve_Java Path resolve()用法及代码示例
- Excel 技巧百例:数据透视表的排序
- Ubuntu下正确姿势使用GDB调试Android Native进程
- 圆桌会回顾 | SecureBoost:挑战千万级别样本训练之性能提升篇
- 江苏大学二本计算机专业排名,2018江苏大学排名 江苏有哪些大学