codeforces 803G Periodic RMQ Problem
2017-05-25 14:57
369 查看
题意:放大版的区间更新的线段树
题解:由于实际上操作并不会生成太多节点,而且只有更新才会生成新节点,如果查询的时候发现下面并没有节点,就知道下面没有更新而且原来数组是循环的,所以直接得到答案,如果更新过就会有节点生成,就如同原来一样计算就行,更新操作就像如同原来的线段树一样,只是如果当前节点不存在就给他生成一个。
ps:看到有人是用离线算法写的,有兴趣的同学可以去学习下姿势。
题解:由于实际上操作并不会生成太多节点,而且只有更新才会生成新节点,如果查询的时候发现下面并没有节点,就知道下面没有更新而且原来数组是循环的,所以直接得到答案,如果更新过就会有节点生成,就如同原来一样计算就行,更新操作就像如同原来的线段树一样,只是如果当前节点不存在就给他生成一个。
ps:看到有人是用离线算法写的,有兴趣的同学可以去学习下姿势。
#include <stdio.h> #include <math.h> using namespace std; #define maxn 5000222 #define maxa 100005 inline int min(int a,int b){return a<b?a:b;} int read() { char c=getchar(); int u=0,f=1; while(c!='-' && (c<'0' || '9'<c))c=getchar(); if(c=='-'){ f=-1; c=getchar(); } while('0'<=c && c<='9'){ u=u*10+c-'0'; c=getchar(); } return u*f; } struct node { int l,r; int x,y; }; node rr[maxn]; int cur=1,n; int s[maxa]; int dp[maxa][20]; void RMQ_init() { for(int i=1; i<=n; i++) dp[i][0]=s[i]; for(int j=1; (1<<j)<=n; j++) for(int i=1;i+(1<<j)-1<=n;i++) dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); } int RMQ(int l, int r) { int k = int(log((double)(r-l+1))/log(2.0)); return min(dp[l][k], dp[r - (1<<k) + 1][k]); } int query_rmq(int L,int R) { if(R-L+1>=n) return RMQ(1,n); else { int l=(L-1)%n+1; int r=(R-1)%n+1; if(r>=l) return RMQ(l,r); else return min(RMQ(l,n),RMQ(1,r)); } } void push_down(int tt) { if(rr[tt].y==1) { if(rr[tt].l==0)rr[tt].l=++cur; rr[rr[tt].l].x=rr[tt].x; rr[rr[tt].l].y=1; if(rr[tt].r==0)rr[tt].r=++cur; rr[rr[tt].r].x=rr[tt].x; rr[rr[tt].r].y=1; } rr[tt].y=0; } int query(int L,int R,int l,int r,int tt) { if(tt==0) { return query_rmq(l,r); } if(l==L&&r==R) { return rr[tt].x; } push_down(tt); int mid=(L+R)/2; if(mid>=r) { return query(L,mid,l,r,rr[tt].l); } else if(mid<l) { return query(mid+1,R,l,r,rr[tt].r); } else { return min(query(L,mid,l,mid,rr[tt].l),query(mid+1,R,mid+1,r,rr[tt].r)); } } void add(int L,int R,int l,int r,int x,int tt) { if(l==L&&r==R) { rr[tt].x=x; rr[tt].y=1; return ; } push_down(tt); int mid=(L+R)/2; if(mid>=r) { if(rr[tt].l==0)rr[tt].l=++cur; add(L,mid,l,r,x,rr[tt].l); } else if(mid<l) { if(rr[tt].r==0)rr[tt].r=++cur; add(mid+1,R,l,r,x,rr[tt].r); } else { if(rr[tt].l==0)rr[tt].l=++cur; add(L,mid,l,mid,x,rr[tt].l); if(rr[tt].r==0)rr[tt].r=++cur; add(mid+1,R,mid+1,r,x,rr[tt].r); } rr[tt].x=min(rr[tt].l==0?query_rmq(L,mid):rr[rr[tt].l].x, rr[tt].r==0?query_rmq(mid+1,R):rr[rr[tt].r].x); } int main() { int m,k,l,r,x,t; scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) { s[i]=read(); } RMQ_init(); rr[1].x=RMQ(1,n); scanf("%d",&m); for(int i=0;i<m;i++) { t=read(); if(t==1) { l=read(); r=read(); x=read(); add(1,n*k,l,r,x,1); } else { l=read(); r=read(); printf("%d\n",query(1,n*k,l,r,1)); } } return 0; }
相关文章推荐
- codeforces 803G Periodic RMQ Problem
- AC日记——Periodic RMQ Problem codeforces 803G
- Codeforces 803 G. Periodic RMQ Problem
- (WAWAWAWAWAWAW) G. Periodic RMQ Problem
- Educational Codeforces Round 20 G. Periodic RMQ Problem(线段树+主席树)
- Educational Codeforces Round 20 G. Periodic RMQ Problem(线段树动态开点)
- CodeForces 17 A.Noldbach problem(水~)
- BZOJ 3489 A simple rmq problem
- The Water Problem(RMQ)
- Luogu4137:Rmq Problem/mex
- CodeForces 165C - Another Problem on Strings
- Codeforces 456 Problem D A Lot of Games
- CodeForces - 633B A Trivial Problem(找规律)
- 【codeforces 749A】Bachgold Problem
- 【BZOJ】【3489】A simple rmq problem
- bzoj 3489: A simple rmq problem (KD-tree)
- HDOJ 5443 The Water Problem 【RMQ 模板题】
- BZOJ 3339: Rmq Problem 莫队算法
- CodeForces - 1000D:Yet Another Problem On a Subsequence (DP+组合数)
- Codeforces Round #427 (Div. 2) Problem B The number on the board (Codeforces 835B) - 贪心