CSU 1110线段树

C - RMQ with Shifts

Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%lld
& %llu

Submit Status Practice CSU
1110

Appoint description: 
System Crawler  (2015-03-10)

Description

In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each query (L, R) (L<=R), 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}.

Input

There will be only one test case, beginning with two integers n, q (1<=n<=100,000, 1<=q<=120,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 30 characters, with no space characters inside. All operations are guaranteed to be valid. Warning: The dataset is large, better to use
faster I/O methods.

Output

For each query, print the minimum value (rather than index) in the requested range.

Sample Input

7 5
6 2 4 8 5 1 4
query(3,7)
shift(2,4,5,7)
query(1,4)
shift(1,2)
query(2,2)

Sample Output

1
4
6 
152ms
分析:题目中说了a string having no more than 30 characters ,说明每次操作数据量比较小,可以用线段树直接搞,写代码的时候有很多细节要注意,不然就各种wrong,
#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;

const int MAXN=100010;

int n,m;
int a[MAXN];

int shift[40];
char s[50];

struct node
{
  int l,r;
  int minn;
}st[MAXN*4];

void build(int v,int l,int r)
{
    st[v].l=l;
    st[v].r=r;
    if(l==r)
    {
      st[v].minn=a[l];
      return ;
    }
    int mid=(l+r)/2;
    build(2*v,l,mid);
    build(2*v+1,mid+1,r);
    st[v].minn=min(st[2*v].minn,st[2*v+1].minn);
}

void update(int v,int id,int key)
{
    if(st[v].l==st[v].r&&st[v].l==id)
    {
       st[v].minn=key;
       return ;
    }
    int mid=(st[v].l+st[v].r)/2;
    if(id<=mid)
        update(2*v,id,key);
    else
        update(2*v+1,id,key);
    st[v].minn=min(st[2*v].minn,st[2*v+1].minn);
}

int RMQ(int v,int l,int r)
{
   if(st[v].l==l &&st[v].r==r)
        return st[v].minn;
   int mid=(st[v].l+st[v].r)/2;
   if(r<=mid)
      return RMQ(2*v,l,r);
   else if(l>mid)
       return RMQ(2*v+1,l,r);
   else
   {
       int t1=RMQ(2*v,l,mid);
       int t2=RMQ(2*v+1,mid+1,r);
       return min(t1,t2);
   }
}

int main()
{
   while(scanf("%d%d",&n,&m)!=EOF)
   {
       for(int i=1;i<=n;i++)scanf("%d",&a[i]);
       build(1,1,n);
       //cout<<st[1].minn<<endl;
       while(m--)
       {
           scanf("%s",s);
           if(s[0]=='q')
           {
               int l=0,r=0,i,j;
               for(i=6;s[i]!=',';i++)l=l*10+(s[i]-'0');
               for(j=i+1;s[j]!=')';j++)r=r*10+(s[j]-'0');

              // cout<<l<<" "<<r<<endl;
               printf("%d\n",RMQ(1,l,r));
           }
           else
           {
               int base=0,ct=0;
               for(int i=6;s[i]!=')';)
               {
                   if(s[i]==',')
                   {
                      i++;
                      shift[++ct]=base;
                      base=0;
                      continue;
                   }
                   base=base*10+(s[i]-'0');
                   i++;
               }
               shift[++ct]=base;

               int tmp=a[shift[1]];
               for(int i=2;i<=ct;i++)
               {
                   a[shift[i-1]]=a[shift[i]];
               }
               a[shift[ct]]=tmp;
               for(int i=1;i<=ct;i++)update(1,shift[i],a[shift[i]]);
            }
       }

   }
   return 0;
}

时间: 2024-08-27 03:18:25

CSU 1110线段树的相关文章

csu 1555(线段树经典插队模型-根据逆序数还原序列)

1555: Inversion Sequence Time Limit: 2 Sec  Memory Limit: 256 MBSubmit: 469  Solved: 167[Submit][Status][Web Board] Description For sequence i1, i2, i3, … , iN, we set aj to be the number of members in the sequence which are prior to j and greater to

csu 1551(线段树+DP)

1551: Longest Increasing Subsequence Again Time Limit: 2 Sec  Memory Limit: 256 MBSubmit: 267  Solved: 112[Submit][Status][Web Board] Description Give you a numeric sequence. If you can demolish arbitrary amount of numbers, what is the length of the

CSU 1453: 平衡序列 学会线段树后必做

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1453. 题目:给定一个大小为100000的数组,里面的数字最大也是100000.现在叫你求出一段子序列,使得他们任意两个数差的绝对值都不能超过k 其实这题的关键是数字的范围,不超过100000,这样的话 ,就可以用线段树整段覆盖了.记dp[i]为以这个数字为结尾的,最长的LIS的多少,开始的时候dp[i]=0,用线段树把他覆盖了.每次插入一个数a[i]的时候,都去找[a[i]-k,a[i]+k]

CSU 1542 Flipping Parentheses(线段树)

1542: Flipping Parentheses Time Limit: 5 Sec  Memory Limit: 256 MB Submit: 289  Solved: 79 [Submit][Status][Web Board] Description Input Output Sample Input 6 3 ((())) 4 3 1 Sample Output 2 2 1 HINT 题目大意: 给出一个长度为n的已经匹配的括号字符串,然后有Q次操作,每次操作会翻转一个括号,让你翻转最

【线段树】CSU 1414 Query on a Tree

点击打开链接 线段树新功能get,太神奇了啊@[email protected] 先遍历下树,时间戳记录下前后时间 子节点的前后时间都会在父节点的前后时间范围内 用线段树维护区间内深度最大和深度最小 #include <cstdio> #include <cstring> #include <cstdlib> #include <string> #include <iostream> #include <algorithm> #inc

csu 1809 Parenthesis(线段树)

#include<bits/stdc++.h> using namespace std; const int maxn=1e5+5; char s[maxn]; int pre[maxn],Min[maxn<<2]; int n,q,u,v; /* 给一个长度为n(<=1e5)的只有()的匹配字符串,q(<=1e5)次询问 每次询问在原串上交换两个字符,问交换之后是否还是合法子串 如果把(值为1,)值为-1,那么一个区间前缀和不存在<0,并且 最终的和为0,肯定就

CSU 1532: JuQueen(线段树)

1532: JuQueen Time Limit: 5 Sec  Memory Limit: 512 MB Submit: 363  Solved: 110 [Submit][Status][Web Board] Description Input Output Sample Input 10 10 5 state 0 groupchange 2 9 7 state 9 groupchange 0 2 10 change 0 -5 Sample Output 0 7 7 3 -3 HINT 题意

ACM学习历程—SNNUOJ 1110 传输网络((并查集 &amp;&amp; 离线) || (线段树 &amp;&amp; 时间戳))(2015陕西省大学生程序设计竞赛D题)

Description Byteland国家的网络单向传输系统可以被看成是以首都 Bytetown为中心的有向树,一开始只有Bytetown建有基站,所有其他城市的信号都是从Bytetown传输过来的.现在他们开始在其他城市陆 续建立了新的基站,命令“C x“代表在城市x建立了一个新的基站,不会在同一个城市建立多个基站:城市编号为1到n,其中城市1就是首都Bytetown.在建立基站的过程中他们还 会询问某个城市的网络信号是从哪个城市传输过来的,命令”Q x“代表查询城市x的来源城市. Inpu

[ACM] SCU 1555 Inversion Sequence (线段树)

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1555 输入5个数 1 2 0 1 0 表示1前面有1个比它大的数,2前面有2个比它大的数-.. 求一个1~n的排列,比如这个就输出3 1 5 2 4 1前面有1个比它大的数,那么1肯定在第二位 2前面有2个比它大的数,那么2肯定排在第四位,有一位被1占了. 3前面有0个比它大的数,那么3肯定在第一位 维护线段树,叶子结点的值为1,维护和.从左到右找第多少个1就可以了. 比如1前面有1个比它大的数