【线段树】bzoj3747 [POI2015]Kinoman】的更多相关文章

BZOJ3747 POI2015 Kinoman Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l<=r<=n),并观看第l,l+1,-,r天内所有的电影.如果同一部电影你观看多于一次,你会感到无聊,于是无法获得这部电影的好看值.所以你希望最大化观看且仅观看过一次的电影的好看值的总和. Input 第一行两个整数n,m(1<=m<=n<…
传送门 简单题. 先不管时间复杂度看看怎么做. 对于一段区间[l,r],如果从右端加入一个数a[r+1],对这个区间有什么影响?显然如果区间中已经有了a[r+1]这个数就会产生-a[i+1]的影响,否则就会产生a[i+1]的影响. 于是对于每个数维护一个pred[i]表示上一个a[i]这个数值的下标. 如果我们枚举右端点i,对于每一个i维护一个[j,i]的最大值.这样每次相当于对[pred[i]+1,i]这段区间做一个区间加,对[pred[pred[i]]+1,pred[i]]有一个区间减的效果…
传送门 线段树经典运用. 设$last_i$表示上一个与$i$相同的类型.然后每次更新$[last[i]+1,i]$和$[last[last[i]]+1,last[i]]$的答案就行了. //BZOJ 3747 //by Cydiater //2016.10.28 #include <iostream> #include <queue> #include <map> #include <ctime> #include <cmath> #inclu…
Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l<=r<=n),并观看第l,l+1,…,r天内所有的电影.如果同一部电影你观看多于一次,你会感到无聊,于是无法获得这部电影的好看值.所以你希望最大化观看且仅观看过一次的电影的好看值的总和. Input 第一行两个整数n,m(1<=m<=n<=1000000). 第二行包含n个整数f[1]…
题解:http://www.cnblogs.com/zyfzyf/p/4105184.html 一.下传标记写法 #include<cstdio> #include<algorithm> #include<cmath> using namespace std; #define lson rt<<1,l,m #define rson rt<<1|1,m+1,r ],f,c; inline void R(int &x){ c=;f=; ; ;…
[BZOJ3747][POI2015]Kinoman Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l<=r<=n),并观看第l,l+1,…,r天内所有的电影.如果同一部电影你观看多于一次,你会感到无聊,于是无法获得这部电影的好看值.所以你希望最大化观看且仅观看过一次的电影的好看值的总和. Input 第一行两个整数n,m(1<=m<=n&…
题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3747 对于这种题,考虑固定区间的右端点为r,设区间左端点为l能取得的好看值总和为a[l],那么就相当于当r取不同取值时所有al的最大值. 设last[i]表示第i部电影上一次出现的位置,当右端点r右移1位时,因为只有看了一遍的电影能获取好看值,所以能取得f[r]的好看值的al只能是在last[r]~r这个区间.因此每次右移时,last[last[r]]+1~last[r]减去w[f[r…
题目描述 一个长度为n的序列,每个数为1~m之一.求一段连续子序列,使得其中之出现过一次的数对应的价值之和最大. 输入 第一行两个整数n,m(1<=m<=n<=1000000). 第二行包含n个整数f[1],f[2],…,f[n](1<=f[i]<=m). 第三行包含m个整数w[1],w[2],…,w[m](1<=w[j]<=1000000). 输出 输出观看且仅观看过一次的电影的好看值的总和的最大值. 样例输入 9 4 2 3 1 1 4 1 2 4 1 5 3…
Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l<=r<=n),并观看第l,l+1,…,r天内所有的电影.如果同一部电影你观看多于一次,你会感到无聊,于是无法获得这部电影的好看值.所以你希望最大化观看且仅观看过一次的电影的好看值的总和. Input 第一行两个整数n,m(1<=m<=n<=1000000). 第二行包含n个整数f[1]…
Kinoman bzoj-3747 POI-2015 题目大意:有m部电影,第i部电影的好看值为w[i].现在放了n天电影,请你选择一段区间l~r使得l到r之间的好看值总和最大.特别地,如果同一种电影放了两遍及以上,那么这种电影的好看值将不会被获得. 注释:$1\le m \le n \le 10^6$. 想法:和rmq problem类似的,我们处理出每一个位置pos右边第一个和pos上电影种类相同的位置nxt[pos].然后,我从1-n扫一遍,每次讲l+1到nxt[l]-1之间的值加上w[a…
3747: [POI2015]Kinoman Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 553  Solved: 222[Submit][Status][Discuss] Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l<=r<=n),并观看第l,l+1,…,r天内所有的电影.如果同一部电影你观看多…
3747: [POI2015]Kinoman Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 830  Solved: 338 Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l<=r<=n),并观看第l,l+1,…,r天内所有的电影.如果同一部电影你观看多于一次,你会感到无聊,于是无法获得这部电影的好看值…
3747: [POI2015]Kinoman Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 715  Solved: 294[Submit][Status][Discuss] Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l<=r<=n),并观看第l,l+1,…,r天内所有的电影.如果同一部电影你观看多…
枚举左区间线段树维护最大值 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<vector> #include<cmath> #include<queue> #include<set> #include<map> #define ll l…
Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l<=r<=n),并观看第l,l+1,…,r天内所有的电影.如果同一部电影你观看多于一次,你会感到无聊,于是无法获得这部电影的好看值.所以你希望最大化观看且仅观看过一次的电影的好看值的总和. Input 第一行两个整数n,m(1<=m<=n<=1000000). 第二行包含n个整数f[1]…
标题效果:有m点,每个点都有一个权值.现在我们有这个m为点的长度n该序列,寻求区间,它仅出现一次在正确的点区间内值和最大 想了很久,甚至神标题,奔说是水的问题--我醉了 枚举左点 对于每个请求留点右键点 树维护最大值 考虑每一个数对答案的贡献 记录一个数组next表示这个位置上的点下一次出现的位置 那么这个点贡献的作用范围就是[i,next[i]-1] 假设没有next就是[i,n] 于是我们先把全部第一个出现的数对答案的贡献增加线段树 然后从左到右扫一遍 每次统计完答案之后把i对答案的贡献去除…
BZOJ_3747_[POI2015]Kinoman_线段树 Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l<=r<=n),并观看第l,l+1,…,r天内所有的电影.如果同一部电影你观看多于一次,你会感到无聊,于是无法获得这部电影的好看值.所以你希望最大化观看且仅观看过一次的电影的好看值的总和. Input 第一行两个整数n,m(1<=m<…
[BZOJ4383][POI2015]Pustynia Description 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r,k以及接下来k个正整数,表示a[l],a[l+1],...,a[r-1],a[r]里这k个数中的任意一个都比任意一个剩下的r-l+1-k个数大(严格大于,即没有等号).请任意构造出一组满足条件的方案,或者判断无解. Input 第一行包含三个正整数n,s,m(1<=s<=n<=100000…
BZOJ_4383_[POI2015]Pustynia_线段树优化建图+拓扑排序 Description 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r,k以及接下来k个正整数,表示a[l],a[l+1],...,a[r-1],a[r]里这k个数中的任意一个都比任意一个剩下的r-l+1-k个数大(严格大于,即没有等号). 请任意构造出一组满足条件的方案,或者判断无解. Input 第一行包含三个正整数n,s,m(1<=s<…
P3588 [POI2015]PUS 对于每个$(l,r,k)$,将$k$个位置向剩下$r-l-k+1$个位置连边,边权为$1$,这样就保证$k$个位置比剩下的大 先给所有位置填$1e9$保证最优 然后拓扑排序填数 填的数不在$[1,1e9]$内或者出现环,即为不合法 但是这样边数过多会超时 于是考虑线段树优化建图 把$n$个点建成线段树,每个节点向左右儿子连边,边权为0. 这样每次连一个区间$[l,r]$就只需要$log(r-l+1)$次 注意不合法情况要枚举完整 #include<iostr…
P3588 [[POI2015]PUS] 终于有个能让我一遍过的题了,写篇题解纪念一下 给定长度为n的序列和其中部分已知的数,还有m个大小关系:区间\([l,r]\)中,有k个给定的数比剩下的\(r-l+1-k\)个数都大 求是否有解,有解给出任意一个合法方案 按大小关系,从大的数向小的数连边 直接建图肯定不行,考虑用线段树优化,如果你不会线段树优化建边,点这里 对于每个\([l,r]\)的区间,这k个给定的数会把区间分成\(k+1\)个小区间 新建一个虚拟节点,这k个数分别向虚拟节点连边,这个…
Problem Link : BZOJ 3747 题解:ZYF-ZYF 神犇的题解 解题的大致思路是,当区间的右端点向右移动一格时,只有两个区间的左端点对应的答案发生了变化. 从 f[i] + 1 到 i 的区间中的答案增加了 W[A[i]], 从 f[f[i]] + 1 到 f[i] 的区间的答案减少了 W[A[i]] ,其余区间的答案没有发生变化. 那么就是线段树的区间修改和区间最值查询. 代码如下: #include <iostream> #include <cstdio>…
题解: 水题 从左向右维护以每一个作为右端点的最大值 线段树维护 代码: #include <bits/stdc++.h> using namespace std; #define rint register ll #define IL inline #define rep(i,h,t) for (rint i=h;i<=t;i++) #define dep(i,t,h) for (rint i=t;i>=h;i--) #define mid ((h+t)>>1) #d…
题意 题目链接 Sol 显然整个序列的形态对询问没什么影响 设权值\(>=s\)的有\(k\)个. 我们可以让这些数每次都被选择 那么剩下的数,假设值为\(a_i\)次,则可以\(a_i\)次被选择 一个显然的思路是每次选最大的C个 那么只需要判断\(\sum a_i >=(c - k)*s\)即可 权值线段树维护一下 #include<bits/stdc++.h> #define Pair pair<int, int> #define MP(x, y) make_pa…
题面 传送门 题解 先考虑暴力怎么做,我们把所有\(r-l+1-k\)中的点向\(x\)连有向边,表示\(x\)必须比它们大,那么如果这张图有环显然就无解了,否则的话我们跑一个多源最短路,每个点的\(dis\)就是它的答案 然而这里边数太多了,所以得线段树优化建边 //minamoto #include<bits/stdc++.h> #define R register #define ls (p<<1) #define rs (p<<1|1) #define fp(i…
题面 bzoj权限题传送门 luogu传送门 思路 首先,这个题目显然可以从所有小的点往大的连边,然后如果没环就一定可行,从起点(入读为0)开始构造就好了 但是问题来了,如果每个都连的话,本题中边数是$O(n^2)$级别的,显然会挂 发现两条性质: 1.所有的限制条件中,给定的总点数不超过3e5个 2.是一个点比一段区间大 第二个条件决定了我们可以利用线段树优化建图,而第一个条件告诉了我们,本题的总边数应该是$sumk\astlog_2n$级别的 那么就做完了 注意拓扑排序的时候有个技巧,把连向…
题目描述 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r,k以及接下来k个正整数,表示a[l],a[l+1],...,a[r-1],a[r]里这k个数中的任意一个都比任意一个剩下的r-l+1-k个数大(严格大于,即没有等号).请任意构造出一组满足条件的方案,或者判断无解. 输入 第一行包含三个正整数n,s,m(1<=s<=n<=100000,1<=m<=200000).接下来s行,每行包含两个正整数p[…
收获挺大的一道题. 这里的限制大小可以做差分约束,从$y\to x$连$1$,表示$y\le x-1$即$y<x$,然后跑最长路求解. 但是,如果这样每次$k+1$个小区间每个点都向$k$个断点连边显然爆炸..考虑优化建边. 发现这里是每个小区间各点连边,所以可以线段树优化,不过每个小区间都要向$k$个点连边还是爆炸,这时候,考虑一种类似于线段树建边里面区间向区间的连边方式:这一边的各个拆分的小区间向一个虚点连边,这个虚点再向另一个区间拆分的小区间连边,保证了边数=区间数=$\log$级别.那这…
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4383 题解 暴力的做法显然是把所有的条件拆分以后暴力建一条有向边表示小于关系. 因为不存在零环,所以随后可以用拓扑排序来解决. 考虑如何优化. 第一个优化比较显而易见,对于一个条件,新建一个虚点,连向所有给出的点. 第二个是,我们可以发现,给定这 \(k\) 个点以后,实际上需要建的边是从最多 \(k + 1\) 个区间中引出的,所以可以考虑线段树优化建图. 然后就可以和上面一样的,因为不存…
problem 线段树优化建图,拓扑,没了. #include <bits/stdc++.h> #define ls(x) ch[x][0] #define rs(x) ch[x][1] #define rep(i , j , k) for(int i = j ; i <= k ; i ++) #define Rep(i , j , k) for(int i = j ; i >= k ; i --) using namespace std ; using ll = long lon…