暴力打满直接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]的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. 2021.9.22考试总结[NOIP模拟59]

    T1 柱状图 关于每个点可以作出两条斜率绝对值为\(1\)的直线. 将绝对值拆开,对在\(i\)左边的点\(j\),\(h_i-i=h_j-j\),右边则是把减号换成加号. 把每个点位置为横坐标,高度 ...

  7. 2021.9.21考试总结[NOIP模拟58]

    T1 lesson5! 开始以为是个无向图,直接不懂,跳去T2了. 之后有看了一眼发现可暴力,于是有了\(80pts\). 发现这个图是有拓扑序的,于是可以用拓扑排序找最长路径.先找原图内在最长路径上 ...

  8. 2021.9.20考试总结[NOIP模拟57]

    (换个编辑器代码就SB地不自动折叠了.. T1 2A 考察快读的写法. $code:$ T1 #include<bits/stdc++.h> #define scanf SCANF=sca ...

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

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

随机推荐

  1. JS边角料: NodeJS+AutoJS+WebSocket+TamperMonkey实现局域网多端文字互传

    ---阅读时间约 7 分钟,复现时间约 15 分钟--- 由于之前一直在用的扩展 QPush 停止服务了,苦于一人凑齐了 Window, Android, Mac, ios 四种系统的设备,Apple ...

  2. 并发容器之ConcurrentMap

    一.concurentMap 1.数据结构,分段数组segment不扩容,里面的table扩容,每次翻倍,table中放的是entry链表的头地址: 2.初始化 segment和table的长度都是2 ...

  3. JDBC使用案例

    一.结果集中获取数据并对实体set值,封装成对象返回: 2.封装JDBC工具类 只要执行一次的,如读取配置文件,则写静态代码块: 异常抛出要写明方法才可以throw,静态代码块异常只能捕捉try ca ...

  4. Java 简介与安装、语法说明、数据类型

    目录 Java 介绍 Java 简介 Java 语言跨平台原理 JRE 和 JDK JDK 下载/安装说明 Java 语法说明 注释 关键字 标识符 数据类型 基本数据类型 引用数据类型 隐式类型转换 ...

  5. Spirit带你彻底了解事件捕获和冒泡机制

    Dom标准事件模型 在Dom标准事件模型中,事件是先进行捕获,达到目标阶段时,在进行冒泡的 捕获阶段==>目标阶段==>冒泡阶段 目标元素和非目标元素 在介绍事件捕获和事件冒泡前 我们先要 ...

  6. C# 中 AppDomain 的一些理解

    C# 中 AppDomain 的一些理解 前言 一直想写一个这样的程序:与其它的程序完全解耦,但可以动态的加载其它程序,并执行其中的特定方法,执行完后可以卸载,完全不影响该程序本身.最近无意间发现了 ...

  7. Jwt的新手入门教程

    Jwt的新手入门教程 1.Jwt究竟是什么东东? ​ 先贴官网地址:JSON Web Tokens - jwt.io ​ ​ 再贴官方的定义: What is JSON Web Token? JSON ...

  8. 一文让你彻底理解SQL的子查询

    什么是子查询 当一个查询是另一个查询的条件时,称之为子查询. 为什么要使用子查询 在SELECT.INSERT.UPDATE或DELETE命令中只要是表达式的地方都可以包含子查询,子查询甚至可以包含在 ...

  9. Go变量与基础数据类型

    一.基础介绍 Go 是静态(编译型)语言,是区别于解释型语言的弱类型语言(静态:类型固定,强类型:不同类型不允许直接运算) 例如 python 就是动态强类型语言 1.Go 的特性: 跨平台的编译型语 ...

  10. Vue router中携带参数与获取参数

    Vue router中携带参数与获取参数 携带参数 query方式,就是?+&结构,例如/login?id=1 <router-link :to="{ name:'login' ...