2021.8.16考试总结[NOIP模拟41]
T1 你相信引力吗
肯定是单调栈维护。但存在重复值,还是个环,不好搞。
发现取区间时不会越过最大值,因此以最大值为断点将环断为序列。在栈里维护当前栈中有多少个与当前元素相等的元素,小分类讨论一下。
最后作为最大值的断点可以与栈中剩下的每个元素组成点对。
$code:$
1 #include<bits/stdc++.h>
2 #define LL long long
3 using namespace std;
4 const int NN=5e6+5;
5 int n,m,top,mx,h[NN<<1],stk[NN<<1],cnt[NN<<1];
6 LL ans;
7 inline int read(){
8 int x=0,f=1; char ch=getchar();
9 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
10 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
11 return x*f;
12 }
13 inline void write(LL x,char sp){
14 char ch[20]; int len=0;
15 if(x<0){ putchar('-'); x=~x+1; }
16 do{ ch[len++]=x%10+(1<<5)+(1<<4); x/=10; }while(x);
17 for(int i=len-1;~i;i--) putchar(ch[i]); putchar(sp);
18 }
19 signed main(){
20 n=read();
21 for(int i=1;i<=n;i++){
22 h[i+n]=h[i]=read();
23 if(h[i]>h[mx]) mx=i;
24 }
25 for(int i=mx;i<mx+n;i++){
26 while(top&&stk[top]<h[i]) --top, ++ans;
27 if(stk[top]>h[i]) ++ans;
28 else ans+=cnt[top]+(h[i]!=h[mx]);
29 stk[++top]=h[i];
30 cnt[top]=(stk[top-1]==h[i])?(cnt[top-1]+1):1;
31 }
32 while(top>2){
33 if(stk[top]==stk[2]) break;
34 --top; ++ans;
35 }
36 write(ans,'\n');
37 return 0;
38 }
T1
T2 marshland
范围$50$,棋盘,带限制,考虑网络流。
黑白染色,将危险点看作黑点。发现每次覆盖都将占据黑点左右中一个白点,上下中一个白点。让奇偶行白点分列二分图两边即可。
在二分图两列点间插黑点,把黑点拆成入点和出点,中间连费用为危险值的边。跑“最大费用可行流”即可。
$code:$
1 #include<bits/stdc++.h>
2 using namespace std;
3 const int NN=1e6+10,inf=2e9;
4 int to[NN<<1],nex[NN<<1],head[NN],c[NN<<1],w[NN<<1],idx=1;
5 int s,t,incf[NN],pre[NN],dis[NN],flow,value,ans;
6 int n,m,k,sum,val[55][55];
7 bool stp[55][55],vis[NN];
8 inline int id(int x,int y){ return (x-1)*n+y; }
9 inline void link(int a,int b,int x,int y){ to[++idx]=b; nex[idx]=head[a]; head[a]=idx; c[idx]=x; w[idx]=y; }
10 inline void add(int a,int b,int x,int y){ link(a,b,x,y); link(b,a,0,-y); }
11 inline int read(){
12 int x=0,f=1; char ch=getchar();
13 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
14 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
15 return x*f;
16 }
17 inline void write(int x,char sp){
18 char ch[20]; int len=0;
19 if(x<0){ putchar('-'); x=~x+1; }
20 do{ ch[len++]=x%10+(1<<5)+(1<<4); x/=10; }while(x);
21 for(int i=len-1;~i;i--) putchar(ch[i]); putchar(sp);
22 }
23 inline bool SPFA(){
24 queue<int>q;
25 memset(dis,-0x3f,sizeof(dis));
26 memset(vis,0,sizeof(vis));
27 q.push(s); dis[s]=0; incf[s]=inf; vis[s]=1;
28 while(!q.empty()){
29 int x=q.front(); q.pop(); vis[x]=0;
30 for(int i=head[x];i;i=nex[i]){
31 if(!c[i]) continue;
32 int v=to[i];
33 if(dis[v]<dis[x]+w[i]){
34 dis[v]=dis[x]+w[i];
35 incf[v]=min(incf[x],c[i]);
36 pre[v]=i;
37 if(!vis[v]) vis[v]=1, q.push(v);
38 }
39 }
40 }
41 return dis[t]>0;
42 }
43 void MCMF(){
44 while(SPFA()){
45 int i,x=t;
46 if(flow+incf[t]>m) break;
47 flow+=incf[t];
48 value=max(value,value+dis[t]*incf[t]);
49 while(x!=s){
50 i=pre[x];
51 c[i]-=incf[t];
52 c[i^1]+=incf[t];
53 x=to[i^1];
54 }
55 }
56 }
57 signed main(){
58 n=read(); m=read(); k=read(); s=(n*n<<1)+1; t=s+1; idx=1;
59 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) val[i][j]=read(), sum+=val[i][j];
60 for(int i=1;i<=k;i++) stp[read()][read()]=1;
61 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){
62 if(stp[i][j]) continue;
63 if((i+j)&1) add(id(i,j),id(i,j)+n*n,1,val[i][j]);
64 else if(i&1){
65 add(s,id(i,j),1,0);
66 if(i>1) add(id(i,j),id(i-1,j),1,0);
67 if(i<n) add(id(i,j),id(i+1,j),1,0);
68 if(j>1) add(id(i,j),id(i,j-1),1,0);
69 if(j<n) add(id(i,j),id(i,j+1),1,0);
70 } else{
71 add(id(i,j),t,1,0);
72 if(i>1) add(id(i-1,j)+n*n,id(i,j),1,0);
73 if(i<n) add(id(i+1,j)+n*n,id(i,j),1,0);
74 if(j>1) add(id(i,j-1)+n*n,id(i,j),1,0);
75 if(j<n) add(id(i,j+1)+n*n,id(i,j),1,0);
76 }
77 }
78 ans=sum; MCMF();
79 write(ans-value,'\n');
80 return 0;
81 }
T2
T3 party?
树形结构,每个人走到所有人的$LCA$。
暴力可以网络流,但我太laji。。(为啥联赛会一场两道网络流???
构造二分图,左边是人,右边是特产,特产连边容量为$1$,二分人与源点连边的容量即为答案。
如果把连边容量为$mid$改为将每个人拆为$mid$个点,问题就转化为求二分图完美匹配。于是有没听说过的霍尔定理:
一个二分图存在完美匹配,当且仅当左部点$x$中任意$k$个点都与右部点$y$中至少$k$个点邻接。
于是可以不用二分。枚举人的所有子集,用它们对应特产数除以人数,取$min$后即为每人最多能带的特产数。
特产可以用$bitset$加树剖维护。维护一个点到它$top$路径上的特产集合可以在树剖时减少一个$log$。
$code:$
1 #include<bits/stdc++.h>
2 #define bst bitset<1024>
3 using namespace std;
4 const int NN=3e5+5;
5 int n,c,m,q,to[NN<<1],nex[NN<<1],head[NN],idx,pla[6],a[NN],ans;
6 int dep[NN],son[NN],siz[NN],top[NN],dfn[NN],fa[NN],id[NN],cnt;
7 bst b[NN];
8 inline int read(){
9 int x=0,f=1; char ch=getchar();
10 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
11 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
12 return x*f;
13 }
14 inline void write(int x,char sp){
15 char ch[20]; int len=0;
16 if(x<0){ putchar('-'); x=~x+1; }
17 do{ ch[len++]=x%10+(1<<5)+(1<<4); x/=10; }while(x);
18 for(int i=len-1;~i;i--) putchar(ch[i]); putchar(sp);
19 }
20 inline void add(int a,int b){
21 to[++idx]=b; nex[idx]=head[a]; head[a]=idx;
22 to[++idx]=a; nex[idx]=head[b]; head[b]=idx;
23 }
24 struct segment_tree{
25 #define ld rt<<1
26 #define rd (rt<<1)|1
27 bst bs[NN<<2];
28 void pushup(int rt){
29 bs[rt]=bs[ld]|bs[rd];
30 }
31 void build(int rt,int l,int r){
32 if(l==r){ bs[rt][a[id[l]]]=1; return; }
33 int mid=l+r>>1;
34 build(ld,l,mid);
35 build(rd,mid+1,r);
36 pushup(rt);
37 }
38 bst query(int rt,int l,int r,int opl,int opr){
39 if(l>=opl&&r<=opr) return bs[rt];
40 int mid=l+r>>1;
41 bst tmp;
42 if(opl<=mid) tmp|=query(ld,l,mid,opl,opr);
43 if(opr>mid) tmp|=query(rd,mid+1,r,opl,opr);
44 return tmp;
45 }
46 }s;
47 void dfs1(int s,int f){
48 fa[s]=f; dep[s]=dep[f]+1; siz[s]=1;
49 for(int i=head[s];i;i=nex[i]){
50 int v=to[i];
51 if(v==f) continue;
52 dfs1(v,s);
53 siz[s]+=siz[v];
54 if(siz[son[s]]<siz[v]) son[s]=v;
55 }
56 }
57 void dfs2(int s,int t){
58 dfn[s]=++cnt; id[cnt]=s; top[s]=t;
59 if(s!=t) b[s]=b[fa[s]]; b[s].set(a[s]);
60 if(!son[s]) return;
61 dfs2(son[s],t);
62 for(int i=head[s];i;i=nex[i]){
63 int v=to[i];
64 if(v!=fa[s]&&v!=son[s]) dfs2(v,v);
65 }
66 }
67 bst S(int x,int lca){
68 bst tmp;
69 while(top[x]!=top[lca]) tmp|=b[x], x=fa[top[x]];
70 tmp|=s.query(1,1,n,dfn[lca],dfn[x]);
71 return tmp;
72 }
73 inline int LCA(int x,int y){
74 while(top[x]!=top[y]){
75 if(dep[top[x]]<dep[top[y]]) swap(x,y);
76 x=fa[top[x]];
77 }
78 return dep[x]<dep[y]?x:y;
79 }
80 signed main(){
81 n=read(); m=read(); q=read();
82 for(int i=2;i<=n;i++) add(i,read());
83 for(int i=1;i<=n;i++) a[i]=read();
84 dfs1(1,0); dfs2(1,1); s.build(1,1,n);
85 while(q--){
86 c=read(); ans=INT_MAX;
87 for(int i=1;i<=c;i++) pla[i]=read();
88 int lca=LCA(pla[1],pla[2]);
89 for(int i=3;i<=c;i++) lca=LCA(lca,pla[i]);
90 bst path[6];
91 for(int i=1;i<=c;i++) path[i]|=S(pla[i],lca);
92 for(int i=1;i<1<<c;i++){
93 path[0].reset();
94 int cntt=0;
95 for(int j=0;j<c;j++)
96 if(i&(1<<j)) path[0]|=path[j+1], cntt++;
97 ans=min(ans,(int)path[0].count()/cntt);
98 }
99 write(ans*c,'\n');
100 }
101 return 0;
102 }
T3
2021.8.16考试总结[NOIP模拟41]的更多相关文章
- 2021.9.17考试总结[NOIP模拟55]
有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...
- 2021.7.15考试总结[NOIP模拟16]
ZJ模拟D2就是NB.. T1 Star Way To Heaven 谁能想到这竟是个最小生成树呢?(T1挂分100的高人JYF就在我身边 把上边界和下边界看成一个点和星星跑最小生成树,从上边界开始跑 ...
- 2021.9.13考试总结[NOIP模拟52]
T1 路径 考虑每一位的贡献,第$i$位每$2^i$个数会变一次,那么答案为$\sum_{i=1}^{log_2n} \frac{n}{2^i}$. $code:$ 1 #include<bit ...
- 2021.8.11考试总结[NOIP模拟36]
T1 Dove玩扑克 考场并查集加树状数组加桶期望$65pts$实际$80pts$,考后多开个数组记哪些数出现过,只扫出现过的数就切了.用$set$维护可以把被删没的数去掉,更快. $code:$ 1 ...
- 2021.7.29考试总结[NOIP模拟27]
T1 牛半仙的妹子图 做法挺多的,可以最小生成树或者最短路,复杂度O(cq),c是颜色数. 我考场上想到了原来做过的一道题影子,就用了并查集,把边权排序后一个个插入,记录权值的前缀和,复杂度mlogm ...
- 2021.9.14考试总结[NOIP模拟53]
T1 ZYB和售货机 容易发现把每个物品都买成$1$是没有影响的. 然后考虑最后一个物品的方案,如果从$f_i$向$i$连边,发现每个点有一个出度多个入度,可以先默认每个物品都能买且最大获利,这样可以 ...
- 2021.9.12考试总结[NOIP模拟51]
T1 茅山道术 仔细观察发现对于每个点只考虑它前面第一个与它颜色相同的点即可. 又仔细观察发现对一段区间染色后以这个区间内点为端点的区间不能染色. 于是对区间右端点而言,区间染色的贡献为遍历到区间左端 ...
- 2021.9.9考试总结[NOIP模拟50]
T1 第零题 神秘结论:从一个点满体力到另一个点的复活次数与倒过来相同. 于是预处理出每个点向上走第$2^i$个死亡点的位置,具体实现可以倍增或二分. 每次询问先从两个点同时向上倍增,都转到离$LCA ...
- 2021.9.7考试总结[NOIP模拟49]
T1 Reverse $BFS$暴力$O(n^2)$ 过程中重复枚举了很多点,考虑用链表记录当前点后面可到达的第一个未更新点. 搜索时枚举翻转子串的左端点,之后便可以算出翻转后$1$的位置. $cod ...
随机推荐
- Tars | 第8篇 TarsJava Subset最终代码的执行流程与原理分析
目录 前言 1. SubsetConf配置项的结构 1.1 SubsetConf 1.2 RatioConfig 1.3 KeyConfig 1.4 KeyRoute 1.5 SubsetConf的结 ...
- 【第十九篇】- Maven NetBeans之Spring Cloud直播商城 b2b2c电子商务技术总结
Maven NetBeans NetBeans 6.7 及更新的版本已经内置了 Maven.对于以前的版本,可在插件管理中心获取 Maven 插件.此例中我们使用的是 NetBeans 6.9. 关于 ...
- Windows 10 之 WSL 2
Windows Subsystem for Linux(WSL)无疑大大提升了Windows下程序开发的体验. WSL 2向开发者提供的完整的系统调用兼容,使得许多无法在WSL 1中安装的应用,如Do ...
- python中安装第三方库(使用豆瓣的镜像网站快速安装)
#安装第三方库#标准库,第三方库#pip install selenium 直接从官网进行安装,有时网速会有点慢#可以去国内的镜像站安装#pip install selenium -i https:/ ...
- 使用git克隆仓库到本地报错:SSL certificate problem: unable to get local issuer certificate
第一次使用Git工具克隆仓库,使用的是HTTPS链接,失败了.发现是因为通过HTTPS访问时,如果服务器上的SSL证书未经过第三方机构认证,Git就会报错. 解决方法:通过命令关闭验证 git con ...
- git实战-linux定时监控github更新状态(二)
系列文章 git介绍-常用操作(一)✓ git实战-linux定时监控github更新状态(二)✓ 本文主要内容 如何查看github的本地仓库和远程仓库的同步情况 linux服务器定时监控githu ...
- trait能力在PHP中的使用
相信大家对trait已经不陌生了,早在5.4时,trait就已经出现在了PHP的新特性中.当然,本身trait也是特性的意思,但这个特性的主要能力就是为了代码的复用. 我们都知道,PHP是现代化的面向 ...
- Shell系列(38)- 数组操作→取值、遍历、替换、删除
引言 在Linux平台上工作,我们经常需要使用shell来编写一些有用.有意义的脚本程序.有时,会经常使用shell数组.那么,shell中的数组是怎么表现的呢,又是怎么定义的呢?接下来逐一的进行讲解 ...
- P1088 [NOIP2004 普及组] 火星人
题目描述 人类终于登上了火星的土地并且见到了神秘的火星人.人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法.这种交流方法是这样的,首先,火星人把一个非常大的数字告诉人类科学 ...
- ios web 媒体查询兼容
原文:https://blog.csdn.net/dear_zx/article/details/82785250 防止链接丢失,复制一下 兼容iphone4/4s: @media (device-h ...