K Seq HihoCoder - 1046 || BZOJ4504 k个串
这题与超级钢琴类似,然而重复的不重复计算贡献。。
那么先求出数组nxt,nxt[i]表示第i个元素之后的第一个与其相等的元素的下标,不存在则nxt[i]=0
考虑取的区间左端点为1时的情况。
将读入序列a中相等元素都只保留最先出现的,其余变为0,然后求前缀和,得到数组b。
此时可以知道,设f(l,r)为取下标在[l,r]区间内数时的答案,那么f(1,r)=b[r]。
考虑取的区间左端点为2时的情况。如何维护b数组,使得新的b数组也满足f(2,r)=b[r]?
手模样例区间左端点为1和2时符合要求的b。
样例:
- 7 5
- 3 -2 1 2 2 1 3
l=1: 3 1 2 4 4 4 4
l=2: 0 -2 -1 1 1 1 4
可以发现,做的操作相当于将b数组内下标在[1,nxt[1]-1]区间内的数减了(原来的)b[1]。
进一步推出,左端点为l时的b数组变到左端点l+1的b数组,就相当于将下标在[l,nxt[l]-1]区间内的数减了(原来的)b[l]。
(当然如果nxt[i]=0,那么就是将[l,n]内减b[l])
因此,可以用可持久化线段树处理出左端点为每一个位置时的b数组。可持久化线段树如果要传标记的话常数会很大(复杂度应该是对的...大概吧?),所以可以标记永久化
(不知道为什么网上的标记永久化那么长?吓得我还以为自己写错了233333)
(我写标记永久化时候困难重重,最后发现标记含义的定义还是类比普通线段树最容易实现(就是除当前节点外,以当前节点为根的子树内所有点的对应值都应加上当前节点的加法tag),另外给标记和记录的值一个明确的定义对于写清楚代码非常重要)
这样子之后就可以用类似超级钢琴的做法去做了...才怪。难道你真的跟我一样想要去写可持久化的带区间修改的区间第k大这样子一看就不靠谱的东西?
可以发现每一次对给定某一个b数组的查询,每次的区间都是一样的,一定是第一次第1大,第二次第2大,...
当然就可以用超级钢琴的后一种做法去做了(优先队列维护一下哪个b数组,哪一段区间的最大值是多少,在哪里,当某一段区间最大值被取出后,把该区间除了最大值所在位置剩下的最多两段取最大值放回优先队列)。'
(似乎也可以考虑暴力将原来的最大值加一个-inf?这样子下一次查找找到的就是该区间的次大啦(我没试过))
错误记录:
1.不知道为什么想到去维护最小值了,怎么过的样例啊
2.82-83行i+1写成i
- #include<cstdio>
- #include<algorithm>
- #include<queue>
- #include<tr1/unordered_map>
- #define inf 0x3f3f3f3f3f3f3f3f
- #define mid ((l+r)>>1)
- using namespace std;
- using namespace tr1;
- typedef long long LL;
- typedef pair<LL,LL> P;
- LL lc[],rc[],addv[],mem;
- //addv[i]表示i区间加法tag
- P maxn[];//一对值:区间(只考虑自身及其下节点的标记)的最大值及下标
- LL L,R,x;
- LL root[],nxt[],a[],b[];
- tr1::unordered_map<LL,LL> ttt1;
- void build(LL l,LL r,LL &num)
- {
- num=++mem;
- if(l==r) {maxn[num]=P(b[l],l);return;}
- build(l,mid,lc[num]);build(mid+,r,rc[num]);
- maxn[num]=max(maxn[lc[num]],maxn[rc[num]]);
- }
- void addx(LL l,LL r,LL &num)
- {
- LL t=num;num=++mem;lc[num]=lc[t];rc[num]=rc[t];maxn[num]=maxn[t];addv[num]=addv[t];
- if(L<=l&&r<=R)
- {
- addv[num]+=x;maxn[num].first+=x;
- return;
- }
- if(L<=mid) addx(l,mid,lc[num]);
- if(mid<R) addx(mid+,r,rc[num]);
- maxn[num]=max(maxn[lc[num]],maxn[rc[num]]);
- maxn[num].first+=addv[num];
- }
- P query(LL l,LL r,LL num)
- {
- if(L<=l&&r<=R) return maxn[num];
- P ans=P(-inf,);
- if(L<=mid) ans=max(ans,query(l,mid,lc[num]));
- if(mid<R) ans=max(ans,query(mid+,r,rc[num]));
- ans.first+=addv[num];
- return ans;
- }
- struct Info
- {
- Info(LL a=,LL b=,LL c=,LL d=,LL e=)
- :ans(a),l(b),r(c),st(d),pos(e)
- {}
- LL ans,l,r,st,pos;
- //root[st]中,[l,r]内最大值是ans,在pos位置
- friend bool operator<(const Info &a,const Info &b)
- {
- return a.ans<b.ans;
- }
- };
- LL n,k;
- priority_queue<Info> q;
- int main()
- {
- LL i;P t;Info t2;
- scanf("%lld%lld",&n,&k);
- for(i=;i<=n;i++) scanf("%lld",&a[i]);
- for(i=;i<=n;i++)
- {
- b[i]=b[i-];
- if(ttt1.count(a[i])==)
- b[i]+=a[i];
- else
- nxt[ttt1[a[i]]]=i;
- ttt1[a[i]]=i;
- }
- build(,n,root[]);
- L=,R=n,t=query(,n,root[]);
- q.push(Info(t.first,,n,,t.second));
- for(i=;i<n;i++)
- {
- root[i]=root[i-];
- L=i,R=i,x=-query(,n,root[i]).first;
- L=i,R=nxt[i]?nxt[i]-:n,addx(,n,root[i]);
- L=i+/**/,R=n,t=query(,n,root[i]);
- q.push(Info(t.first,i+,n,i,t.second));//
- }
- for(i=;i<k;i++)
- {
- t2=q.top();q.pop();
- L=t2.l,R=t2.pos-;
- if(L<=R)
- {
- t=query(,n,root[t2.st]);
- q.push(Info(t.first,L,R,t2.st,t.second));
- }
- L=t2.pos+,R=t2.r;
- if(L<=R)
- {
- t=query(,n,root[t2.st]);
- q.push(Info(t.first,L,R,t2.st,t.second));
- }
- }
- t2=q.top();
- printf("%lld",t2.ans);
- return ;
- }
K Seq HihoCoder - 1046 || BZOJ4504 k个串的更多相关文章
- hihocoder#1046: K个串
[传送门] 这种区间内相同数字只能被统计一次/只有区间内数字都不相同才对答案有贡献的题都可以用扫描线扫右端点,表示当前区间右端点为$r$.然后当前线段树/树状数组维护区间左端点为$[1,r)$时对应的 ...
- HihoCoder - 1807:好的数字串 (KMP DP)
Sample Input 6 1212 Sample Output 298 给定一个数字字符串S,如果一个数字字符串(只包含0-9,可以有前导0)中出现且只出现1次S,我们就称这个字符串是好的. 例如 ...
- 机器学习理论与实战(十)K均值聚类和二分K均值聚类
接下来就要说下无监督机器学习方法,所谓无监督机器学习前面也说过,就是没有标签的情况,对样本数据进行聚类分析.关联性分析等.主要包括K均值聚类(K-means clustering)和关联分析,这两大类 ...
- BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 418 Solved: 235 [ Submit][ ...
- 在数组a中,a[i]+a[j]=a[k],求a[k]的最大值,a[k]max——猎八哥fly
在数组a中,a[i]+a[j]=a[k],求a[k]的最大值,a[k]max. 思路:将a中的数组两两相加,组成一个新的数组.并将新的数组和a数组进行sort排序.然后将a数组从大到小与新数组比较,如 ...
- [Swift]LeetCode347. 前K个高频元素 | Top K Frequent Elements
Given a non-empty array of integers, return the k most frequent elements. Example 1: Input: nums = [ ...
- [Swift]LeetCode692. 前K个高频单词 | Top K Frequent Words
Given a non-empty list of words, return the k most frequent elements. Your answer should be sorted b ...
- [leetcode]340. Longest Substring with At Most K Distinct Characters至多包含K种字符的最长子串
Given a string, find the length of the longest substring T that contains at most k distinct characte ...
- 【POJ】2449.Remmarguts' Date(K短路 n log n + k log k + m算法,非A*,论文算法)
题解 (搬运一个原来博客的论文题) 抱着板题的心情去,结果有大坑 就是S == T的时候也一定要走,++K 我发现按照论文写得\(O(n \log n + m + k \ log k)\)算法没有玄学 ...
随机推荐
- Spring3.2+mybatis3.2+Struts2.3整合配置文件大全
0.配置文件目录 1.Spring配置 applicationContext-dao.xml <?xml version="1.0" encoding="UTF-8 ...
- ****HTML模板资源汇总
站长素材: http://sc.chinaz.com/tag_moban/HTML.html wordpress模板: http://www.cssmoban.com/wpthemes/ http:/ ...
- 动态链接 - dll和so文件区别与构成
动态链接,在可执行文件装载时或运行时,由操作系统的装载程序加载库.大多数操作系统将解析外部引用(比如库)作为加载过程的一部分.在这些系统上,可执行文件包含一个叫做import directory的 ...
- 基于端口的信息探测-portscan-1.0
http://www.tiaozhanziwo.com/archives/174.html
- hdu - 2645 find the nearest station (bfs水)
http://acm.hdu.edu.cn/showproblem.php?pid=2645 找出每个点到距离最近的车站的距离. 直接bfs就好. #include <cstdio> #i ...
- 创建Django项目(三)——站点管理
2013-08-05 21:01:34| 1.激活管理界面 (1) 修改"mysite\mysite\settings.py"文件,将'django ...
- CSS3(各UI元素状态伪类选择器受浏览器的支持情况)
选择器 Firefox Safari Opera IE Chrome E:hover Y Y Y Y Y E:active Y Y Y N Y E:focus Y Y Y Y Y E:enabled ...
- JSTL-函数标签库
主页:http://www.cnblogs.com/EasonJim/p/6958992.html的分支页. 一.fn:contains() fn:contains()函数决定了一个输入字符串是否包含 ...
- [Debug] Inspect and Style an Element in DevTools that Normally Disappears when Inactive
It’s handy to inspect an element in your browser’s DevTools when you need to experiment or tweak it’ ...
- 设计模式之外观模式(Facade)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...