zoukankan      html  css  js  c++  java
  • Loj 504 ZQC的手办

    Loj 504 ZQC的手办

    • 用线段树维护,每个节点存储区间内最小值 (val) 以及最小值出现的一个位置 (pos) .
    • 对操作 (1) ,只需打标记即可,因为我们不维护其他的信息(如区间和),只对最小值修改,容易完成.
    • 对操作 (2) ,用一个四元组 ((l,r,v,pos))(v) 形成的小根堆来查询区间前 (x) 小的值,每次取出堆顶,加入答案,再不断对线段树询问 (p) 两侧的 ((val,pos)),插入堆中,重复做 (x) 次即可.注意特判元素不足或堆顶 (vgeq x) 的无解情况.
    • 总时间复杂度为 (O(logncdot (n+sum x))).

    以前好像做过一道类似的题?总之用线段树同时维护最小值即其位置是一种经典的套路做法.

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define mp make_pair
    #define pii pair<int,int>
    #define root Tree[o]
    #define lson Tree[o<<1]
    #define rson Tree[o<<1|1]
    #define inf (1e9)+7
    inline int read()
    {
    	int x=0;
    	bool pos=1;
    	char ch=getchar();
    	for(;!isdigit(ch);ch=getchar())
    		if(ch=='-')
    			pos=0;
    	for(;isdigit(ch);ch=getchar())
    		x=x*10+ch-'0';
    	return pos?x:-x;
    }
    const int MAXN=5e5+10;
    int n,m;
    struct node{
    	int l,r;
    	int val,pos;
    	int tag;
    	node()
    		{
    			tag=0;
    		}
    }Tree[MAXN<<2];
    struct data{
    	int l,r,v,pos;
    	data(int x,int y,int c,int d)
    		{
    			l=x,r=y,v=c,pos=d;
    		}
    	bool operator < (const data &rhs) const
    		{
    			return v>rhs.v;
    		}
    };
    priority_queue<data> q;
    vector<int> ans;
    int a[MAXN];
    void pushup(int o)
    {
    	if(lson.val<rson.val)
    		root.pos=lson.pos;
    	else
    		root.pos=rson.pos;
    	root.val=min(lson.val,rson.val);
    }
    void Modifiy(int o,int v)
    {
    	root.val=max(root.val,v);
    	root.tag=v;
    }
    void pushdown(int o)
    {
    	if(root.tag)
    		{
    			Modifiy(o<<1,root.tag);
    			Modifiy(o<<1|1,root.tag);
    			root.tag=0;
    		}
    }
    void BuildTree(int o,int l,int r)
    {
    	root.l=l,root.r=r;
    	if(l==r)
    		{
    			root.pos=l;
    			root.val=a[l];
    			return;
    		}
    	int mid=(l+r)>>1;
    	BuildTree(o<<1,l,mid);
    	BuildTree(o<<1|1,mid+1,r);
    	pushup(o);
    }
    void update(int o,int L,int R,int k)
    {
    	int l=root.l,r=root.r;
    	if(l>R || r<L)
    		return;
    	if(L<=l && r<=R)
    		{
    			Modifiy(o,k);
    			return;
    		}
    	pushdown(o);
    	int mid=(l+r)>>1;
    	if(L<=mid)
    		update(o<<1,L,R,k);
    	if(R>mid)
    		update(o<<1|1,L,R,k);
    	pushup(o);
    }
    pii query(int o,int L,int R)//min,pos
    {
    	int l=root.l,r=root.r;
    	pii res=mp(inf,-1);
    	if(l>R || r<L)
    		return res;
    	if(L<=l && r<=R)
    		return mp(root.val,root.pos);
    	pushdown(o);
    	int mid=(l+r)>>1;
    	if(L<=mid)
    		res=min(res,query(o<<1,L,R));
    	if(R>mid)
    		res=min(res,query(o<<1|1,L,R));
    	return res;
    }
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;++i)
    		a[i]=read();
    	BuildTree(1,1,n);
    	m=read();
    	while(m--)
    		{
    			int op=read(),l=read(),r=read(),k=read();
    			if(op==1)
    				update(1,l,r,k);
    			else
    				{
    					int x=read();
    					if(r-l+1<x)
    						{
    							puts("-1");
    							continue;
    						}
    					while(!q.empty())
    						q.pop();
    					ans.clear();
    					pii u=query(1,l,r);
    					q.push(data(l,r,u.first,u.second));
    					for(int i=1;i<=x;++i)
    						{
    							data u=q.top();
    							q.pop();
    							if(u.v<k)
    								ans.push_back(u.v);
    							else
    								break;
    							if(u.l<u.pos)
    								{
    									pii w=query(1,u.l,u.pos-1);
    									q.push(data(u.l,u.pos-1,w.first,w.second));
    								}
    							if(u.r>u.pos)
    								{
    									pii w=query(1,u.pos+1,u.r);
    									q.push(data(u.pos+1,u.r,w.first,w.second));
    								}
    						}
    					int siz=ans.size();
    					if(siz<x)
    						puts("-1");
    					else
    						{
    							for(int i=0;i<siz;++i)
    								printf("%d ",ans[i]);
    							puts("");
    						}
    				}
    		}
    	return 0;
    }
    
  • 相关阅读:
    (16)JavaScript的流程控制(js的循环)
    (15)javaScript入门
    (14)定位布局(子级在父级中自由定位 父级在页面中自由定位)
    (0-1)CSS 标签语法的属性
    ACM/ICPC 之 双向链表_构造列表-模拟祖玛 (TSH OJ-Zuma(祖玛))
    手记-数学分析(高等数学)中有关算法效率的公式列举(O,Θ,Ω)
    2014北大研究生推免机试(校内)-复杂的整数划分(DP进阶)
    整数划分问题-解法汇总(暂有DP-递归)
    2014北大研究生推免机试(校内)-垃圾炸弹(基础枚举)
    ACM/ICPC 之 BFS-广搜进阶-八数码(经典)(POJ1077+HDU1043)
  • 原文地址:https://www.cnblogs.com/jklover/p/10397556.html
Copyright © 2011-2022 走看看