2021.8.5考试总结[NOIP模拟31]
暴力打满直接rk3?
T1 Game
想了一万种贪心和两万种$hack$。
可以先用最显然的贪心求出最高得分是多少。(从小到大用最小的大于$b_i$的$a$得分)
然后用一棵权值线段树维护值域内$a$和$b$的个数,发现两个儿子合并对答案的贡献就是$min(a_r,b_l)$。(要用大的$a$对小的$b$)于是最优分数可以直接在建树时算出。
对每个位置考虑放什么数可以令最优分数不下降,发现它是单调的。于是可以二分。具体是把$mid$值删去后检查一遍最优分数有无下降。
对$a_mid$是否大于$b_i$要分类讨论,如果$a_mid$大于$b_i$,检查时要将最终答案$+1$,因为当前位置会贡献$1$。
找到该位答案后把$a_mid$和$b_i$删掉,对最优答案$-1$,使它不会对之后的答案产生影响。
挺妙的,在线段树操作中自动修改最优分数。
$code:$
1 #include<bits/stdc++.h>
2 #define ld rt<<1
3 #define rd (rt<<1)|1
4 #define rin register signed
5 using namespace std;
6 const int NN=1e5+5;
7 int n,a[NN],pre[NN],b[NN],ans[NN],an[NN],bota[NN],k,it,botb[NN],tk;
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){
15 char ch[20]; int len=0;
16 if(x<0) putchar('-'), x=~x+1;
17 do{
18 ch[len++]=x%10+(1<<5)+(1<<4);
19 x/=10;
20 }while(x);
21 for(rin i=len-1;i>=0;--i) putchar(ch[i]);
22 return;
23 }
24 struct segment_tree{
25 int suma[NN<<2],sumb[NN<<2],l[NN<<2],r[NN<<2];
26 void pushup(int rt){
27 int tmp=min(suma[rd],sumb[ld]); tk+=tmp;
28 suma[rt]=suma[ld]+suma[rd]-tmp;
29 sumb[rt]=sumb[ld]+sumb[rd]-tmp;
30 }
31 void build(int rt,int opl,int opr){
32 l[rt]=opl; r[rt]=opr;
33 if(opl==opr){
34 suma[rt]=bota[opl];
35 sumb[rt]=botb[opl];
36 return;
37 }
38 int mid=opl+opr>>1;
39 build(ld,opl,mid);
40 build(rd,mid+1,opr);
41 pushup(rt);
42 }
43 void update(int rt,int pos){
44 if(l[rt]==r[rt]){
45 suma[rt]=bota[pos];
46 sumb[rt]=botb[pos];
47 return;
48 }
49 int mid=l[rt]+r[rt]>>1;
50 tk-=min(sumb[ld],suma[rd]);
51 if(pos<=mid) update(ld,pos);
52 else update(rd,pos);
53 pushup(rt);
54 }
55 }s;
56 bool check(int mid,int op){
57 bota[mid]--; s.update(1,mid);
58 int res=tk+op;
59 bota[mid]++; s.update(1,mid);
60 return res==k;
61 }
62 signed main(){
63 n=read(); rin atmp=0;
64 for(rin i=1;i<=n;++i){ b[i]=read(); botb[b[i]]++; }
65 for(rin i=1;i<=n;++i){ int t=read(); bota[t]++; it=max(it,t); }
66 s.build(1,1,it); k=tk;
67 for(rin i=1;i<=n;i++){
68 botb[b[i]]--; s.update(1,b[i]);
69 while(!bota[it]&&it) it--;
70 int l=b[i]+1,r=it,pos=0;
71 while(l<=r){
72 int mid=l+r>>1;
73 if(check(mid,1)) l=mid+1, pos=mid;
74 else r=mid-1;
75 }
76 if(!pos){
77 l=0; r=b[i];
78 while(l<=r){
79 int mid=l+r>>1;
80 if(check(mid,0)) l=mid+1, pos=mid;
81 else r=mid-1;
82 }
83 }
84 else k--;
85 bota[pos]--; s.update(1,pos); ans[i]=pos;
86 }
87 for(int i=1;i<=n;i++) write(ans[i]), putchar(' ');
88 putchar('\n');
89 return 0;
90 }
T1
T2 Time
是个贪心。每次找到序列中的最小值,把它移到左或右端点,哪近移哪。貌似可以分治。
事实上每个点移到它成为最小值时端点对答案的贡献就是它左/有大于它数的个数。树状数组即可。
(到现在我也不知道求逆序对为什么假了
$code:$
1 #include<bits/stdc++.h>
2 #define ld rt<<1
3 #define rd (rt<<1)|1
4 using namespace std;
5 const int NN=1e5+5;
6 int n,p[NN],ans,c[NN],pre[NN],suf[NN];
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(int x){
14 char ch[20]; int len=0;
15 if(x<0) putchar('-'), x=~x+1;
16 do{
17 ch[len++]=x%10+(1<<5)+(1<<4);
18 x/=10;
19 }while(x);
20 for(int i=len-1;i>=0;i--) putchar(ch[i]);
21 return;
22 }
23 inline int lowbit(int x){ return x&(-x); }
24 inline void insert(int pos){
25 while(pos<100000){
26 c[pos]++;
27 pos+=lowbit(pos);
28 }
29 }
30 inline int query(int pos){
31 int res=0;
32 while(pos){
33 res+=c[pos];
34 pos-=lowbit(pos);
35 }
36 return res;
37 }
38 signed main(){
39 n=read();
40 for(int i=1;i<=n;i++)
41 p[i]=read();
42 for(int i=1;i<=n;i++){
43 pre[i]=query(100000)-query(p[i]);
44 insert(p[i]);
45 }
46 memset(c,0,sizeof(c));
47 for(int i=n;i;i--){
48 suf[i]=query(100000)-query(p[i]);
49 insert(p[i]);
50 }
51 for(int i=1;i<=n;i++)
52 ans+=min(pre[i],suf[i]);
53 write(ans); putchar('\n');
54 return 0;
55 }
T2
T3 Cover
是道神题。首先区间不交或包含,可以转化成树上问题。
暴力$DP$挺简单的,定义$f_{i,j}$为$i$子树中最多覆盖$j$层,有:
$f_{i,j}=max(max(\sum f_{son,j-1}+w_i,\sum f_{son,j}),f_{i,j-1})$
然后时空$O(n^2)$全炸了。
注意到很多计算是重复或无用的,而$f_{i,j}$在$i$相同时单调不减,可以直接维护差分。
而因为维护的是最优策略,可以发现差分值也单调不增,然后考虑$\sum f_{son,j-1}+w_i$什么时候能成为最优答案。
首先差分意义下,初始的$f_{i,j}=\sum f_{son,j}$。
那么有$f_{i,j}<f_{i,j-1}+w_i\Rightarrow w_i>f_{i,j}-f_{i,j-1}$,即$w_i$大于$f_{i,j}$与$f_{i,j-1}$的差分值。
于是可以直接用保证数据单调的数据结构(堆,$multiset$)维护差分值,子树合并后直接将$w_i$插入即可。
$code:$
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;
6 int n,m,res;
7 vector<int>son[NN];
8 struct node{
9 int l,r,a;
10 bool operator<(const node& s)const{ return l<s.l||(l==s.l&&r>s.r); }
11 }d[NN];
12 multiset<int>f[NN];
13 stack<int>stk;
14 inline int read(){
15 int x=0,f=1; char ch=getchar();
16 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
17 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
18 return x*f;
19 }
20 inline void write(int x){
21 char ch[20]; int len=0;
22 if(x<0) putchar('-'), x=~x+1;
23 do{
24 ch[len++]=x%10+(1<<5)+(1<<4);
25 x/=10;
26 }while(x);
27 for(int i=len-1;i>=0;i--) putchar(ch[i]);
28 return;
29 }
30 void merge(multiset<int> &a,multiset<int> &b){
31 if(a.size()<b.size()) swap(a,b);
32 vector<int>tmp;
33 for(auto x:b){ tmp.pb(x+*a.begin()); a.erase(a.begin()); }
34 for(auto t:tmp) a.insert(t);
35 }
36 void dfs(int s){
37 for(auto to:son[s]){
38 dfs(to);
39 merge(f[s],f[to]);
40 }
41 f[s].insert(-d[s].a);
42 }
43 signed main(){
44 n=read(); m=read();
45 for(int i=1;i<=m;i++)
46 d[i].l=read(), d[i].r=read(), d[i].a=read();
47 sort(d+1,d+m+1);
48 stk.push(0);
49 for(int i=1;i<=m;i++){
50 while(stk.top()!=0&&d[stk.top()].r<d[i].r) stk.pop();
51 son[stk.top()].pb(i);
52 stk.push(i);
53 }
54 dfs(0);
55 for(int i=1;i<=m;i++){
56 if(f[0].size())
57 res-=*f[0].begin(), f[0].erase(f[0].begin());
58 write(res); putchar(' ');
59 } putchar('\n');
60 return 0;
61 }
T3
2021.8.5考试总结[NOIP模拟31]的更多相关文章
- 2021.9.17考试总结[NOIP模拟55]
有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...
- 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.7.15考试总结[NOIP模拟16]
ZJ模拟D2就是NB.. T1 Star Way To Heaven 谁能想到这竟是个最小生成树呢?(T1挂分100的高人JYF就在我身边 把上边界和下边界看成一个点和星星跑最小生成树,从上边界开始跑 ...
- 2021.9.22考试总结[NOIP模拟59]
T1 柱状图 关于每个点可以作出两条斜率绝对值为\(1\)的直线. 将绝对值拆开,对在\(i\)左边的点\(j\),\(h_i-i=h_j-j\),右边则是把减号换成加号. 把每个点位置为横坐标,高度 ...
- 2021.9.21考试总结[NOIP模拟58]
T1 lesson5! 开始以为是个无向图,直接不懂,跳去T2了. 之后有看了一眼发现可暴力,于是有了\(80pts\). 发现这个图是有拓扑序的,于是可以用拓扑排序找最长路径.先找原图内在最长路径上 ...
- 2021.9.20考试总结[NOIP模拟57]
(换个编辑器代码就SB地不自动折叠了.. T1 2A 考察快读的写法. $code:$ T1 #include<bits/stdc++.h> #define scanf SCANF=sca ...
- 2021.9.14考试总结[NOIP模拟53]
T1 ZYB和售货机 容易发现把每个物品都买成$1$是没有影响的. 然后考虑最后一个物品的方案,如果从$f_i$向$i$连边,发现每个点有一个出度多个入度,可以先默认每个物品都能买且最大获利,这样可以 ...
随机推荐
- Servlet生命周期和方法
一.五个生命周期方法,有三个很重要,初始化方法.提供服务方法和销毁方法 1.三个主要方法 2.另外两个重写的成员方法只做了解 二.生命周期详解 其中,每次刷新页面都是一次对servlet访问: 页面访 ...
- Linux上安装服务器监视工具,名为pyDash。
pyDash – A Web Based Linux Performance Monitoring Tool 你可以通过以下命令来判断是否已安装: pip --version # Python2.x ...
- 洛谷P1781——宇宙总统(高精度排序)
题目描述 地球历公元6036年,全宇宙准备竞选一个最贤能的人当总统,共有n个非凡拔尖的人竟选总统,现在票数已经统计完毕,请你算出谁能够当上总统. 输入输出格式 输入格式: 第一行为一个整数n,代表竞选 ...
- VB自制计算器
使用visual basic编写. 绘制如下的按钮界面: 然后代码如下: Dim a, temp, ans As Integer Dim op As String Sub showans() Text ...
- PHP中一个好玩的性别判断扩展
今天我们来学习的一个扩展同时它也是非常小众的一个扩展,其实说白了,或许是根本没什么人用过得扩展.当然,我们也只是出于学习的目的来看看这个扩展到底是什么东西,有什么好玩的地方. 扩展说明 Gender ...
- MySql WorkBench通过表生成表关系图
1.mysql workbench 菜单file=>add model(添加模型) 点击上面的add diagram(添加新的图解),就会在右边多出一个新的图解模型 2,mysql workbe ...
- win10环境charles抓包unknow问题
win10环境,charles已经安装了证书,但是抓包的时候还是unknow,让人头疼. 1.确保证书安装成功. 2.检查charles设置是否正确. 进入Charles - > Proxy - ...
- Python Type Hints(类型提示)
在做自动化测试的时候,改进测试框架,类型提示会让你写代码时更加流程,当你在一个模块定义了类型,而其他模块没有提示的时候,是相当不方便.
- xadmin使用富文本
环境:pycharm django1.11.20 python2.7 后台xadmin(根据网络各种资料实现) 本教程接上篇如何安装 xadmin,如何不清楚,请看上一篇(django安装xadmin ...
- Centos7下thinkphp5.0环境配置
首先把yum源修改为阿里的yum源,如果没有安装wget,先安装一个.(如果有请蹦过) wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors ...