Noip模拟31 2021.8.5
T1 Game
当时先胡了一发$\textit{Next Permutation}$。。。
然后想正解,只想到贪心能求最大得分,然后就不会了。。
然后就甩个二十分的走了。。。
正解的最大得分(叫它$k$)是在树上维护的。
权值线段树上维护一个$A,B$表示$a,b$权值出现的次数。
那么$A$的右子树权值一定比$B$左子树权值大,每次取$min$递归就能找到$k$
然后考虑如何找到字典需最小方案
每次取出$b$(注意大小写的区分)中一个元素,找有没有比他大的$a$
用二分可以解决
如果没有,就找到比他小的里面最大的合法的$a$
也用二分解决
至于如何实现使用一个$multiset$维护,删除节点信息就行了


- 1 #include<bits/stdc++.h>
- 2 #define lid (id<<1)
- 3 #define rid (id<<1|1)
- 4 using namespace std;
- 5 const int NN=1e6+5;
- 6 int n,a[NN],b[NN],k,ta[NN],tb[NN],ans;
- 7 multiset<int> st;
- 8 struct SNOWtree{
- 9 int ll[NN<<2],rr[NN<<2],A[NN<<2],B[NN<<2];
- 10 inline void pushup(int id){
- 11 if(ll[id]==rr[id]) return;
- 12 int now=min(B[lid],A[rid]); ans+=now;
- 13 A[id]=A[lid]+A[rid]-now;
- 14 B[id]=B[lid]+B[rid]-now;
- 15 }
- 16 void build(int id,int l,int r){
- 17 ll[id]=l; rr[id]=r;
- 18 if(l==r){A[id]=ta[l]; B[id]=tb[l];return;}
- 19 int mid=l+r>>1;
- 20 build(lid,l,mid); build(rid,mid+1,r);
- 21 pushup(id);
- 22 }
- 23 void update(int id,int pos){
- 24 if(ll[id]==rr[id]){A[id]=ta[pos];B[id]=tb[pos];return;}
- 25 ans-=min(B[lid],A[rid]);
- 26 int mid=ll[id]+rr[id]>>1;
- 27 if(pos<=mid) update(lid,pos);
- 28 else update(rid,pos);
- 29 pushup(id);
- 30 }
- 31 }tr;
- 32 inline bool check(int mid,int opt){
- 33 --ta[mid]; tr.update(1,mid);
- 34 int tmp=ans+opt;
- 35 ++ta[mid]; tr.update(1,mid);
- 36 return tmp==k;
- 37 }
- 38 namespace WSN{
- 39 inline short main(){
- 40 scanf("%d",&n);
- 41 for(int i=1;i<=n;i++) scanf("%d",&b[i]),++tb[b[i]];
- 42 for(int i=1;i<=n;i++) scanf("%d",&a[i]),++ta[a[i]],st.insert(a[i]);
- 43 tr.build(1,1,*(--st.end())); k=ans;
- 44 for(int i=1;i<=n;i++){
- 45 --tb[b[i]]; tr.update(1,b[i]);
- 46 int l=b[i]+1,r=*(--st.end()),wsn=0;
- 47 while(l<=r){
- 48 int mid=l+r>>1;
- 49 if(check(mid,1)) l=mid+1,wsn=mid;
- 50 else r=mid-1;
- 51 }
- 52 if(!wsn){
- 53 int ll=0,rr=b[i];
- 54 while(ll<=rr){
- 55 int mid=ll+rr>>1;
- 56 if(check(mid,0)) ll=mid+1,wsn=mid;
- 57 else rr=mid-1;
- 58 }
- 59 }else --k;
- 60 --ta[wsn]; tr.update(1,wsn); st.erase(st.find(wsn));
- 61 printf("%d ",wsn);
- 62 }
- 63 return 0;
- 64 }
- 65 }
- 66 signed main(){return WSN::main();}
T2 Time
一眼找逆序对
然后貌似想到了所有正解
然后不会快速求逆序对。。。。
只会生硬的$O(n^2)$求,比较可恶,对于正解一点优化都加不上
无奈交了$O(n^2)$的暴力求逆序对方法,可恶。。。。。
正解就是扫一遍位置,找到他前面比他大的数有几个(就是求与他构成逆序对的个数)
后面比他大的数有几个(同理,正序对个数),取$min$加和就行了,正确性显然
$18$行的优秀代码,终于比$DeepinC$学长的代码短了一次嘿嘿。


- 1 #include<bits/stdc++.h>
- 2 using namespace std;
- 3 int n,a[1000005],ans=0,tr[1000005],pre[1000005],nxt[1000005];
- 4 inline int lowbit(int x){return x&(-x);}
- 5 inline void update(int x,int v){for(int i=x;i<=n;i+=lowbit(i))tr[i]+=v;}
- 6 inline int query(int x){int ans=0;for(int i=x;i;i-=lowbit(i))ans+=tr[i];return ans;}
- 7 namespace WSN{
- 8 inline short main(){
- 9 scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]);
- 10 for(int k=1;k<=n;k++) pre[k]=k-1-query(a[k]),update(a[k],1);
- 11 for(int i=0;i<=n;i++) tr[i]=0;
- 12 for(int k=n;k>=1;k--) nxt[k]=query(n)-query(a[k]),update(a[k],1);
- 13 for(int k=1;k<=n;k++) ans+=min(pre[k],nxt[k]);
- 14 printf("%d\n",ans);
- 15 return 0;
- 16 }
- 17 }
- 18 signed main(){return WSN::main();}
T3 Cover
包含和不相交关系,构成树,$skyh$讲树形$dp$时说过,
于是这题就是道树形$dp$,然后就不想打了,因为$dp$打不对。。。
想打$dfs$骗分,可是时间却不多,无法细致的调了,惨报零。。。
其实就是建树然后$dp$,那么我们也分两步说
一,建树:
这一方面,我们可以开一个$multiset$存所有的$id$和位置信息
然后递归建树,这一方面你为了正确的进行$\textit{lower_bound}$操作
需要一波重载运算符,然后在每次查的时候$id$赋值$0$,目的是不找到相同的值
前提是在重载运算符时提到关于$id$的比较,详见代码
剩下的只需看区间是否被传递的$l,r$包含,然后递归建边即可,注意跳出就行。
二,$dp$:
设$dp_{i,j}$表示以$i$为根的子树中至多选择$j$个区间的最大美观程度
因为子树内的点表示的区间信息都被$i$的信息所包含
所以这个$j$能够同理表示那个题目里走廊上的点被$j$个彩灯覆盖
于是可以得到状态转移方程:
$dp_{i,j}=max(\sum (dp_{son_i,j-1})+w_i,\sum dp_{son_i,j})$
此时$dp_{i,j}$表示的是恰好选择$j$个区间的美观度
然后需要把它的意义变成至多,要加上一步:
$dp_{i,j}=max(dp_{i,j},dp_{i,j-1})$
发现可以使用差分维护,配合一波$\textit{priority_queue}$就可以维护出答案的差分了
然后前缀和加起来输出即可


- 1 #include<bits/stdc++.h>
- 2 #define int long long
- 3 #define pb push_back
- 4 using namespace std;
- 5 const int NN=3e5+5,inf=2e9;
- 6 int n,m,w[NN],val[NN];
- 7 struct SNOW{
- 8 int l,r,id;
- 9 friend bool operator<(SNOW a,SNOW b){
- 10 return a.l==b.l?(a.r==b.r?a.id<b.id:a.r>b.r):a.l<b.l;
- 11 }
- 12 }s[NN];
- 13 multiset<SNOW> st;
- 14 priority_queue<int> Q[NN];
- 15 vector<int> e[NN];
- 16 inline void build(int id,int l,int r){
- 17 while(!st.empty()){
- 18 auto it=st.lower_bound((SNOW){l,r,0});
- 19 if(it==st.end()) break;
- 20 SNOW k=*it;
- 21 if(l<=k.l&&k.r<=r){
- 22 e[id].pb(k.id);
- 23 st.erase(it);
- 24 build(k.id,k.l,k.r);
- 25 }else break;
- 26 }
- 27 }
- 28 inline void dfs(int x){
- 29 int son=m+1;
- 30 for(int i=0;i<e[x].size();i++){
- 31 dfs(e[x][i]);
- 32 if(Q[e[x][i]].size()>Q[son].size()) son=e[x][i];
- 33 }swap(Q[son],Q[x]);
- 34 for(int i=0;i<e[x].size();i++){
- 35 if(e[x][i]==son) continue;
- 36 int k=Q[e[x][i]].size();
- 37 for(int j=1;j<=k;j++) val[j]=Q[x].top(),Q[x].pop();
- 38 for(int j=1;j<=k;j++) val[j]+=Q[e[x][i]].top(),Q[e[x][i]].pop();
- 39 for(int j=1;j<=k;j++) Q[x].push(val[j]);
- 40 }Q[x].push(w[x]);
- 41 }
- 42 namespace WSN{
- 43 inline short main(){
- 44 scanf("%lld%lld",&n,&m);
- 45 for(int i=1;i<=m;i++){
- 46 s[i].id=i;scanf("%lld%lld%lld",&s[i].l,&s[i].r,&w[i]);
- 47 st.insert(s[i]);
- 48 }build(0,1,n); dfs(0);
- 49 int k=Q[0].size();
- 50 for(int i=1;i<=k;i++) val[i]=Q[0].top(),Q[0].pop();
- 51 for(int i=1;i<=m;i++) val[i]+=val[i-1],printf("%lld ",val[i]);
- 52 return 0;
- 53 }
- 54 }
- 55 signed main(){return WSN::main();}
Noip模拟31 2021.8.5的更多相关文章
- noip模拟31[time·game·cover]
noip模拟31 solutions 我就觉得这些考试题是越考越难,我是也越考越完蛋,已经完完全全的接近爆零了 只有20pts,说真的这还是我第一次挂掉30pts,本来我还有50pts嘞 所以这次考试 ...
- 2021.8.5考试总结[NOIP模拟31]
暴力打满直接rk3? T1 Game 想了一万种贪心和两万种$hack$. 可以先用最显然的贪心求出最高得分是多少.(从小到大用最小的大于$b_i$的$a$得分) 然后用一棵权值线段树维护值域内$a$ ...
- Noip模拟70 2021.10.6
T1 暴雨 放在第一道的神仙题,不同的做法,吊人有的都在用线段树维护$set$预处理 我是直接$dp$的,可能代码的复杂度比那种的稍微小一点 设$f[i][j][p][0/1]$表示考虑了前$i$列, ...
- Noip模拟76 2021.10.14
T1 洛希极限 上来一道大数据结构或者单调队列优化$dp$ 真就没分析出来正解复杂度 正解复杂度$O(q+nm)$,但是据说我的复杂度是假的 考虑一个点转移最优情况是从它上面的一个反$L$形转移过来 ...
- Noip模拟69 2021.10.5
考场拼命$yy$高精度结果没学好$for$循环痛失$50pts$,当场枯死 以后一定打对拍,要不考后会... T1 石子游戏 首先要知道典型的$NIM$博弈,就是说如果所有堆石子个数的异或和为$0$则 ...
- Noip模拟63 2021.9.27(考场惊现无限之环)
T1 电压机制 把题目转化为找那些边只被奇数环包含. 这样的话直接$dfs$生成一棵树,给每个点附上一个深度,根据其他的非树边都是返祖边 可以算出环内边的数量$dep[x]-dep[y]+1$,然后判 ...
- Noip模拟61 2021.9.25
T1 交通 考场上想了一个$NPC$.应该吧,是要求出图里面的所有可行的不重复欧拉路 无数种做法都无法解出,时间也都耗在这个上面的,于是就考的挺惨的 以后要是觉得当前思路不可做,就试着换一换思路,千万 ...
- Noip模拟59 2021.9.22
新机房首模拟变倒数 T1 柱状图 关于每一个点可以做出两条斜率分别为$1,-1$的直线, 然后题意转化为移动最少的步数使得所有点都在某一个点的两条直线上 二分出直线的高度,判断条件是尽量让这条直线上部 ...
- Noip模拟52 2021.9.13
T1 异或 比较稳的切掉 观察数据范围,无法线性筛啥的,根号复杂度也会死,于是只能考虑$log$级 然后打表 发现当$n$为$2^i$时的答案是一个可递归数列: $1,3,7,15,31,63,127 ...
随机推荐
- Python使用openpyxl模块操作Excel表格
''' Excel文件三个对象 workbook: 工作簿,一个excel文件包含多个sheet. sheet:工作表,一个workbook有多个,表名识别,如"sheet1",& ...
- 全网唯一正常能用的centos7 安装mysql5.7.35 22 33 25
CentOS7.4用yum安装并配置MySQL5.7 1.配置YUM源 下载MySQL源安装包 wget http://dev.mysql.com/get/mysql57-community-re ...
- python模块--pathlib
类/属性/方法 返回值 参数 说明 .Path() p 创建Path对象 path 路径 p.parent Path 返回上一级路径 p.parents iter 上一级路径, 上上级 ...
- python库--tensorflow--RNN(循环神经网络相关)
类/方法 返回值类型 参数 说明 tf.contrib.rnn① / tf.nn.rnn_cell② .RNNCell() 实例r 看不懂 trainable=True name=None d ...
- 一文详解JavaScript的继承模式
1 原型链继承 #### ES6中通过原型继承多个引用类型的属性和方法,由于原型和实例的关系,即每个构造函数都有自己的原型对象,同时原型有一个属性指向构造函数,并且实例有一个内部的指针指向原型.如果存 ...
- PHP的命令行扩展Readline相关函数学习
PHP 作为一个 Web 开发语言,相对来说,命令行程序并不是它的主战场.所以很多年轻的 PHP 开发者可能连命令行脚本都没有写过,更别提交互式的命令操作了.而今天,我们带来的这个扩展就是针对 PHP ...
- 5ucms的评论列表该怎么写
查看所有评论 <a href="{sys:plusurl}comment/?id={field:id}">查看所有评论</a> <linkhref=& ...
- lua自写限制并发访问模块
注意:ngx.say跟ngx.exit是不可以共存,否则会出现ngx.exit无法正常执行 1.定义lua共享内存20m lua_shared_dict ceshi 20m; 2.再location ...
- 系统设计实践(03)- Instagram社交服务
前言 系统设计实践篇的文章将会根据<系统设计面试的万金油>为前置模板,讲解数十个常见系统的设计思路. 前置阅读: <系统设计面试的万金油> 系统设计实践(01) - 短链服务 ...
- P2179-[NOI2012]骑行川藏【导数,二分】
正题 题目链接:https://www.luogu.com.cn/problem/P2179 题目大意 给出\(E\)和\(n\)个\(s_i,k_i,u_i\)求一个序列\(v_i\)满足 \[\s ...