zoukankan      html  css  js  c++  java
  • codeforces 803G Periodic RMQ Problem

    codeforces 803G Periodic RMQ Problem

    题意

    长度为(1e5)的数组复制(1e4)次,对新的数组进行区间覆盖和区间最小值查询两种操作,操作次数(1e5)

    参考博客

    http://kugwzk.info/index.php/archives/2404

    题解一

    小数组复用多次变成大数组,那么可以用ST表维护小数组的区间最小值,大数组还是用线段树维护(Min[])(lazy[]),但是不用进行build操作,所以upd和qry操作中标记下传的时候儿子节点可能会不存在,需要动态开点。

    题解二

    离线做法。离散化之后用普通线段树就能搞定。

    总结

    写线段树的题目最重要的是,要知道自己在维护什么东西,每个结点上值的意义都要很清楚。

    代码一

    #include<bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define rep(i, a, b) for(int i=(a); i<(b); i++)
    #define sz(x) (int)x.size()
    #define de(x) cout<< #x<<" = "<<x<<endl
    #define dd(x) cout<< #x<<" = "<<x<<" "
    typedef long long ll;
    typedef pair<int, int> pii;
    typedef vector<int> vi;
    //------
    
    const int N=101010;
    
    int n,k;
    int b[N];
    int st[N][22];
    
    int stmin(int l,int r) {
    	int _=log2(r-l+1);
    	return min(st[l][_], st[r-(1<<_)+1][_]);
    }
    int stMin(int l,int r) {
    	int L=l/n, R=r/n;
    	if(L==R) {
    		return stmin(l%n, r%n);
    	} else if(L+1==R) {
    		return min(stmin(l%n, n-1), stmin(0, r%n));
    	} else {
    		return stmin(0, n-1);
    	}
    }
    
    int cntn;
    int ls[N*244], rs[N*244], mi[N*244], la[N*244];
    
    void down(int rt, int l, int r, int mid) {
    	bool fl=0, fr=0;
    	if(ls[rt]==-1) ls[rt]=++cntn, fl=1;
    	if(rs[rt]==-1) rs[rt]=++cntn, fr=1;
    	int L=ls[rt], R=rs[rt];
    	if(la[rt]) {
    		la[L]=mi[L]=la[rt];
    		la[R]=mi[R]=la[rt];
    		la[rt]=0;
    	} else {
    		if(fl) mi[L]=stMin(l, mid);
    		if(fr) mi[R]=stMin(mid+1, r);
    	}
    }
    
    void upd(int L,int R,int c,int l,int r,int rt) {
    	if(L<=l&&r<=R) {
    		mi[rt]=la[rt]=c;
    		return ;
    	}
    	int mid=l+r>>1;
    	down(rt, l, r, mid);
    	if(L<=mid) upd(L,R,c,l,mid,ls[rt]);
    	if(R>=mid+1) upd(L,R,c,mid+1,r,rs[rt]);
    	mi[rt]=min(mi[ls[rt]], mi[rs[rt]]);
    }
    
    int qry(int L,int R,int l,int r,int rt) {
    	if(L<=l&&r<=R) return mi[rt];
    	int mid=l+r>>1;
    	down(rt, l, r, mid);
    	int ans=1e9+7;
    	if(L<=mid) ans=min(ans, qry(L, R, l, mid, ls[rt]));
    	if(R>=mid+1) ans=min(ans, qry(L, R, mid+1, r, rs[rt]));
    	return ans;
    }
    
    int main() {
    	while(~scanf("%d%d",&n,&k)) {
    		///init
    		cntn=0;
    		memset(la,0,sizeof(la));
    		memset(ls,-1,sizeof(ls));
    		memset(rs,-1,sizeof(rs));
    		///read
    		rep(i,0,n) scanf("%d",b+i);
    		///st_ini
    		rep(i,0,n) st[i][0]=b[i];
    		for(int i=1;(1<<i)<=n;++i) {
    			for(int j=0;j+(1<<i)-1<n;++j) {
    				st[j][i]=min(st[j][i-1], st[j+(1<<(i-1))][i-1]);
    			}
    		}
    		///solve
    		mi[0]=stmin(0, n-1);
    		int q;scanf("%d",&q);
    		while(q--) {
    			int t,l,r;scanf("%d%d%d",&t,&l,&r);
    			--l;--r;
    			if(t==1) {
    				int x;scanf("%d",&x);
    				upd(l, r, x, 0, n*k-1, 0);
    			} else {
    				printf("%d
    ",qry(l, r, 0, n*k-1, 0));
    			}
    		}
    	}
    	return 0;
    }
    

    代码二

    #include<bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define rep(i, a, b) for(int i=(a); i<(b); i++)
    #define sz(x) (int)x.size()
    #define de(x) cout<< #x<<" = "<<x<<endl
    #define dd(x) cout<< #x<<" = "<<x<<" "
    typedef long long ll;
    typedef pair<int, int> pii;
    typedef vector<int> vi;
    //------
    
    const int N=101010;
    
    int n,k,q;
    int st[N][22];
    
    int stmin(int l,int r) {
    	int _=log2(r-l+1);
    	return min(st[l][_], st[r-(1<<_)+1][_]);
    }
    int stMin(int l,int r) {
    	if(l>r) return 1e9+7;
    	int L=l/n, R=r/n;
    	if(L==R) return stmin(l%n, r%n);
    	else if(L+1==R) return min(stmin(l%n, n-1), stmin(0, r%n));
    	else return stmin(0, n-1);
    }
    
    int cntx;
    int x[N<<1], val[N<<2];
    
    struct Q {
    	int t,l,r,x;
    	Q() {}
    	Q(int a,int b,int c,int d) {
    		t=a;l=b;r=c;x=d;
    	}
    }qq[N];
    
    int mi[N<<4], la[N<<4];
    
    void build(int l, int r, int rt) {
    	la[rt]=0;
    	if(l==r) {
    		mi[rt]=val[l];
    		return ;
    	}
    	int mid=l+r>>1;
    	build(l, mid, rt<<1);
    	build(mid+1, r, rt<<1|1);
    	mi[rt]=min(mi[rt<<1], mi[rt<<1|1]);
    }
    
    void down(int rt) {
    	if(la[rt]==0) return ;
    	int L=(rt<<1), R=(L|1);
    	la[L]=mi[L]=la[R]=mi[R]=la[rt];
    	la[rt]=0;
    }
    
    void upd(int L,int R,int c,int l,int r,int rt) {
    	if(L<=l&&r<=R) {
    		mi[rt]=la[rt]=c;
    		return ;
    	}
    	int mid=l+r>>1;
    	down(rt);
    	if(L<=mid) upd(L,R,c,l,mid,rt<<1);
    	if(R>=mid+1) upd(L,R,c,mid+1,r,rt<<1|1);
    	mi[rt]=min(mi[rt<<1], mi[rt<<1|1]);
    }
    
    int qry(int L,int R,int l,int r,int rt) {
    	if(L<=l&&r<=R) return mi[rt];
    	down(rt);
    	int mid=l+r>>1;
    	int ans=1e9+7;
    	if(L<=mid) ans=min(ans,qry(L,R,l,mid,rt<<1));
    	if(R>=mid+1) ans=min(ans,qry(L,R,mid+1,r,rt<<1|1));
    	return ans;
    }
    
    int main() {
    	while(~scanf("%d%d",&n,&k)) {
    		///init
    		cntx=0;
    		///read
    		rep(i,0,n) scanf("%d",&st[i][0]);
    		scanf("%d",&q);
    		rep(i,0,q) {
    			int t,l,r,xx=0;scanf("%d%d%d",&t,&l,&r);
    			--l;--r;
    			if(t==1) scanf("%d",&xx);
    			qq[i]=Q(t,l,r,xx);
    			x[++cntx]=l;
    			x[++cntx]=r;
    		}
    		///st
    		for(int i=1;(1<<i)<=n;++i) {
    			for(int j=0;j+(1<<i)-1<n;++j) {
    				st[j][i]=min(st[j][i-1], st[j+(1<<(i-1))][i-1]);
    			}
    		}
    		///solve
    		sort(x+1,x+1+cntx);
    		cntx=unique(x+1, x+1+cntx)-x-1;
    		rep(i,1,cntx+1) val[i<<1]=st[x[i]%n][0];
    		rep(i,1,cntx) val[i<<1|1]=stMin(x[i]+1, x[i+1]-1);
    		build(2, cntx<<1, 1);
    		rep(i,0,q) {
    			int t=qq[i].t;
    			int l=qq[i].l;
    			int r=qq[i].r;
    			int c=qq[i].x;
    			int L=lower_bound(x+1, x+1+cntx, l)-x;
    			int R=lower_bound(x+1, x+1+cntx, r)-x;
    			if(t==1) {
    				upd(L<<1, R<<1, c, 2, cntx<<1, 1);
    			} else {
    				printf("%d
    ",qry(L<<1, R<<1, 2, cntx<<1, 1));
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Caused by: java.lang.ClassNotFoundException: org.w3c.dom.ElementTraversal
    Linux系统下jar包的启动方式
    1062 Error 'Duplicate entry '1438019' for key 'PRIMARY'' on query
    Linux学习笔记 --iptables防火墙配置
    MySQL学习笔记_10_MySQL高级操作(下)
    MySQL学习笔记_9_MySQL高级操作(上)
    MySQL学习笔记_8_SQL语言基础复习
    Linux 学习笔记_12_文件共享服务_4_SSH
    Linux 学习笔记_12_文件共享服务_3_NFS网络文件服务
    MySQL学习笔记_7_MySQL常用内置函数
  • 原文地址:https://www.cnblogs.com/wuyuanyuan/p/8277100.html
Copyright © 2011-2022 走看看