• 【SSLOJ1476】联


    题目

    思路

    很裸的线段树。对于每次修改,将 \(l,r,r+1\) 插入数组中,然后将数组中的数字离散化。
    每次修改注意标记的下传。询问直接类似权值线段树即可。
    时间复杂度 \(O(n\log n)\)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N=1000010;
    int Q,tot;
    ll b[N];
    
    struct Query
    {
    	ll l,r,opt;
    }ask[N];
    
    struct SegTree
    {
    	int l[N*4],r[N*4],sum[N*4],len[N*4],lazy[N*4];
    	
    	void build(int x,int ql,int qr)
    	{
    		l[x]=ql; r[x]=qr; len[x]=qr-ql+1;
    		if (ql==qr) return;
    		int mid=(ql+qr)>>1;
    		build(x*2,ql,mid); build(x*2+1,mid+1,qr);
    	}
    	
    	void pushdown(int x)
    	{
    		if (lazy[x])
    		{
    			if (lazy[x]==1) sum[x*2]=len[x*2],sum[x*2+1]=len[x*2+1];
    			if (lazy[x]==2) sum[x*2]=sum[x*2+1]=0;
    			if (lazy[x]==3) sum[x*2]=len[x*2]-sum[x*2],sum[x*2+1]=len[x*2+1]-sum[x*2+1];
    			if (lazy[x]==3)
    				lazy[x*2]=3-lazy[x*2],lazy[x*2+1]=3-lazy[x*2+1];
    			else
    				lazy[x*2]=lazy[x*2+1]=lazy[x];
    			lazy[x]=0;
    		}
    	}
    	
    	void pushup(int x)
    	{
    		sum[x]=sum[x*2]+sum[x*2+1];
    	}
    	
    	void update(int x,int ql,int qr,int opt)
    	{
    		pushdown(x);
    		if (l[x]==ql && r[x]==qr)
    		{
    			if (opt==1) sum[x]=len[x];
    			if (opt==2) sum[x]=0;
    			if (opt==3) sum[x]=len[x]-sum[x];
    			lazy[x]=opt;
    			return;
    		}
    		pushdown(x);
    		int mid=(l[x]+r[x])>>1;
    		if (qr<=mid) update(x*2,ql,qr,opt);
    		else if (ql>mid) update(x*2+1,ql,qr,opt);
    		else update(x*2,ql,mid,opt),update(x*2+1,mid+1,qr,opt);
    		pushup(x);
    	}
    	
    	void query(int x)
    	{
    		pushdown(x);
    		if (l[x]==r[x])
    		{
    			printf("%lld\n",b[l[x]]);
    			return;
    		}
    		pushdown(x);
    		if (sum[x*2]<len[x*2]) query(x*2);
    			else query(x*2+1);
    	}
    }seg;
    
    int main()
    {
    	scanf("%d",&Q);
    	b[++tot]=1LL;
    	for (int i=1;i<=Q;i++)
    	{
    		scanf("%lld%lld%lld",&ask[i].opt,&ask[i].l,&ask[i].r);
    		b[++tot]=ask[i].l; b[++tot]=ask[i].r;
    		b[++tot]=ask[i].l+1; b[++tot]=ask[i].r+1;
    	}
    	sort(b+1,b+1+tot);
    	tot=unique(b+1,b+1+tot)-b-1;
    	for (int i=1;i<=Q;i++)
    	{
    		ask[i].l=lower_bound(b+1,b+1+tot,ask[i].l)-b;
    		ask[i].r=lower_bound(b+1,b+1+tot,ask[i].r)-b;
    	}
    	seg.build(1,1,tot);
    	for (int i=1;i<=Q;i++)
    	{
    		int opt=ask[i].opt,l=ask[i].l,r=ask[i].r;
    		seg.update(1,l,r,opt);
    		seg.query(1);
    	}
    	return 0;
    }
    
  • 相关阅读:
    [python工具][1]sublime安装与配置
    [办公软件][1]cmder安装
    [持续集成学习篇]【1】[jenkins安装与配置]
    [python篇] [伯乐在线][1]永远别写for循环
    [python学习篇] uiautomator xiaocong
    SharePoint 2010中重置windows 活动目录(AD)域用户密码的WebPart(免费下载)
    使用SharePoint 2010的母版页
    SharePoint 2013 入门教程--系列文章
    自定义 SharePoint 2010 快速启动栏和顶部链接栏
    SharePoint2010 自定义代码登录方法
  • 原文地址:https://www.cnblogs.com/stoorz/p/13507398.html
Copyright © 2020-2023  润新知