您的位置:首页 > 编程语言 > C语言/C++

线段树变形 568,1012

2015-12-05 22:44 344 查看
描述
In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each query (L, R)(LR),
we report the minimum value among A[L], A[L + 1], ..., A[R]. Note that the indices start from 1, i.e. the left-most element
is A[1].
In this problem, the array A is no longer static: we need to support another operation

shift(i1, i2, i3,..., ik)(i1 < i2 < ... < ik, k > 1)

we do a left ``circular shift" of A[i1], A[i2],
..., A[ik].
For example, if A={6, 2, 4, 8, 5, 1, 4}, then shift(2,
4, 5, 7) yields {6, 8, 4, 5, 4, 1, 2}. After that,shift(1, 2) yields 8, 6, 4, 5, 4, 1, 2.

输入There will be only one test case, beginning with two integers n, q ( 1<=n<=100, 000, 1<=q<=250, 000), the number of integers in array A, and the number of operations. The next line contains n positive integers not greater than 100,000, the initial elements
in array A. Each of the next q lines contains an operation. Each operation is formatted as a string having no more than 100 characters, with no space characters inside. All operations are guaranteed to be valid.输出For each query, print the minimum value (rather than index) in the requested range.写过好几遍,每次都有点小问题,注意!

//一定要注意数据范围!!数组一定要开够!!!细节太多了,这道题就是单点改变更新,思路不难,注意细节!!!
#include<cstdio>
#include<cstring>
using namespace std;
int a[100005];
int father[100005];
struct node{
int l;
int r;
int val;
}t[300005];
int ans;
int n;
int inf=2000000000;
inline int min(int a,int b){
return a>b?b:a;
}
int build(int root,int l,int r){
t[root].l=l;
t[root].r=r;
if (l==r){
father[l]=root;
t[root].val=a[l];
return a[l];
}
return t[root].val=min(build(root*2,l,(l+r)/2),build(root*2+1,(l+r)/2+1,r));
}
void update(int now){
while(now!=0){
t[now].val=min(t[now*2].val,t[now*2+1].val);
//cout<<t[now].val<<" " ;
now/=2;
}
}
int query(int root,int l,int r){
if (t[root].l==l&&t[root].r==r) {
return ans=min(ans,t[root].val);
}
if (l<=t[root*2].r){
if (r<=t[root*2].r) ans=query(root*2,l,r);
else ans=query(root*2,l,t[root*2].r);
}
if (r>=t[root*2+1].l){
if (l>=t[root*2+1].l) ans=query(root*2+1,l,r);
else ans=query(root*2+1,t[root*2+1].l,r);
}
return ans;
}
int main(){
int tt;
int tmp;
int m;
int v[100];
int count;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
build(1,1,n);
char s[110];
int l,r;
while(m--){
scanf("%s",s);
if (s[0]=='q'){
ans=inf;
sscanf(s+5,"(%d,%d)",&l,&r);
printf("%d\n",query(1,l,r));
}
else {
count=0;
tmp=0;
for (int i=6;i<strlen(s);i++){
if(s[i]>='0'&&s[i]<='9'){
tmp=tmp*10+s[i]-'0';
}
else if(s[i]==','||s[i]==')'){
v[count++]=tmp;
tmp=0;
}
}
tt=t[father[v[0]]].val;
for (int i=0;i<count-1;i++){
t[father[v[i]]].val=t[father[v[i+1]]].val;
update( father[v[i]]/2 );
}
t[father[v[count-1]]].val=tt;
update(father[v[count-1]]/2);
}
}
}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ 算法