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]的更多相关文章

  1. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  2. 2021.7.15考试总结[NOIP模拟16]

    ZJ模拟D2就是NB.. T1 Star Way To Heaven 谁能想到这竟是个最小生成树呢?(T1挂分100的高人JYF就在我身边 把上边界和下边界看成一个点和星星跑最小生成树,从上边界开始跑 ...

  3. 2021.9.13考试总结[NOIP模拟52]

    T1 路径 考虑每一位的贡献,第$i$位每$2^i$个数会变一次,那么答案为$\sum_{i=1}^{log_2n} \frac{n}{2^i}$. $code:$ 1 #include<bit ...

  4. 2021.8.11考试总结[NOIP模拟36]

    T1 Dove玩扑克 考场并查集加树状数组加桶期望$65pts$实际$80pts$,考后多开个数组记哪些数出现过,只扫出现过的数就切了.用$set$维护可以把被删没的数去掉,更快. $code:$ 1 ...

  5. 2021.7.29考试总结[NOIP模拟27]

    T1 牛半仙的妹子图 做法挺多的,可以最小生成树或者最短路,复杂度O(cq),c是颜色数. 我考场上想到了原来做过的一道题影子,就用了并查集,把边权排序后一个个插入,记录权值的前缀和,复杂度mlogm ...

  6. 2021.9.14考试总结[NOIP模拟53]

    T1 ZYB和售货机 容易发现把每个物品都买成$1$是没有影响的. 然后考虑最后一个物品的方案,如果从$f_i$向$i$连边,发现每个点有一个出度多个入度,可以先默认每个物品都能买且最大获利,这样可以 ...

  7. 2021.9.12考试总结[NOIP模拟51]

    T1 茅山道术 仔细观察发现对于每个点只考虑它前面第一个与它颜色相同的点即可. 又仔细观察发现对一段区间染色后以这个区间内点为端点的区间不能染色. 于是对区间右端点而言,区间染色的贡献为遍历到区间左端 ...

  8. 2021.9.9考试总结[NOIP模拟50]

    T1 第零题 神秘结论:从一个点满体力到另一个点的复活次数与倒过来相同. 于是预处理出每个点向上走第$2^i$个死亡点的位置,具体实现可以倍增或二分. 每次询问先从两个点同时向上倍增,都转到离$LCA ...

  9. 2021.9.7考试总结[NOIP模拟49]

    T1 Reverse $BFS$暴力$O(n^2)$ 过程中重复枚举了很多点,考虑用链表记录当前点后面可到达的第一个未更新点. 搜索时枚举翻转子串的左端点,之后便可以算出翻转后$1$的位置. $cod ...

随机推荐

  1. 抽奖之Flash大转盘

    1.搭建JS与Flash互通的环境 function thisMovie(movieName){ if (window.document[movieName]) { return window.doc ...

  2. Hello Wolrd

    这是一篇测试文章.....后续会更新一些文章.

  3. Docker Command and Dockerfile

    镜像相关命令 # 下载镜像 docker pull xxx # 搜素镜像 docker search xxx # 查看已经下载了哪些镜像 docker images # 查看已下载镜像的id dock ...

  4. mysql数据库备份参数

    我用来实现自动全备份的脚本(可以满足一般有前后版本兼容要求的导出导入操作,我的字符集是latin1): mysqldump.exe -umyusername -pmypass -h localhost ...

  5. Kafka 3.0新特性

    1.概述 Kafka是一个分布表示实时数据流平台,可独立部署在单台服务器上,也可部署在多台服务器上构成集群.它提供了发布与订阅的功能,用户可以发送数据到Kafka集群中,也可以从Kafka集群中读取数 ...

  6. redis小结 1-1

    1.1什么是resis Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. 1.2Redis 与其他 key - value 缓存产品有以下三个特点 Redis支持 ...

  7. centos 关于yum无法使用

    一.网络问题 1.1 ping # 确认网络是否可以ping通, 通则不是网络问题(跳过), 不通则是网络问题(往下操作) ping www.baidu.com 1.2 检查网络模式 1.关闭虚拟机 ...

  8. Skywalking-09:OAL原理——如何通过动态生成的Class类保存数据

    OAL 如何通过动态生成的 Class 类,保存数据 前置工作 OAL 如何将动态生成的 SourceDispatcher 添加到 DispatcherManager // org.apache.sk ...

  9. Android 开发进程 0.35 升级编译版本Android12

    Android12升级 工作需要升级到编译版本31 在这里记录一下遇到的问题. 错误:Manifest merger failedManifest merger failed 这个问题通常搜到的答案是 ...

  10. HTML选择器的四种使用方法

    选择器<style> 为了让.html代码更加简洁,这里引入选择器style 本文总共介绍选择器的四种使用方式 一.选择器的四种形式 1.ID选择器 id表示身份,在页面元素中的id不允许 ...