zoukankan      html  css  js  c++  java
  • HDU 5063 Operation the Sequence(BestCoder Round #13)

    Problem Description:
    You have an array consisting of n integers: a1=1,a2=2,a3=3,,an=n. Then give you m operators, you should process all the operators in order. Each operator is one of four types:
    Type1: O 1 call fun1();
    Type2: O 2 call fun2();
    Type3: O 3 call fun3();
    Type4: Q i query current value of a[i], this operator will have at most 50.
    Global Variables: a[1…n],b[1…n];
    fun1() {
    index=1;
      for(i=1; i<=n; i +=2) 
        b[index++]=a[i];
      for(i=2; i<=n; i +=2)
        b[index++]=a[i];
      for(i=1; i<=n; ++i)
        a[i]=b[i];
    }
    fun2() {
      L = 1;R = n;
      while(L<R) {
        Swap(a[L], a[R]); 
        ++L;--R;
      }
    }
    fun3() {
      for(i=1; i<=n; ++i) 
        a[i]=a[i]*a[i];
    }
     
    Input:
    The first line in the input file is an integer T(1T20), indicating the number of test cases.
    The first line of each test case contains two integer n(0<n100000)m(0<m100000).
    Then m lines follow, each line represent an operator above.
     
    Output:
    For each test case, output the query values, the values may be so large, you just output the values mod 1000000007(1e9+7).
     
    Sample Input:
    1
    3 5
    O 1
    O 2
    Q 1
    O 3
    Q 1
     
    Sample Output:
    2
    4
    题意:给出三种操作,第一种是将奇数序的数提前,偶数序的数滞后,第二种是前后对称互换位置,第三种是每一位求取平方。

    解题思路:

        因为给定n和m都是100000,我们每一步都做具体的操作,时间将是O(n*m),肯定超时。最开始的时候

    我怎么想都不知道怎么解决。以为是线段树。询问Q i最多50次。所以我们把每部的操作都记下来,每次Q i的时候,

    就反推回去。自己可以推推。假设当前位置为x,我们要求操作之前的位置。

    Fun1:

    n = (n + 1) / 2;

    x = x <= n / 2 ? (2 * x - 1) : ((x - n) * 2);

    Fun2:

    x = n + 1 - x;

    Fun3:

    我们用op记录平方次数。这样处理的时间复杂度O(50*n)。

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<math.h>
    #include<stdlib.h>
    #include<algorithm>
    using namespace std;
    
    const int N=1e5+10;
    const int INF=0x3f3f3f3f;
    const int MOD=1e9+7;
    
    typedef long long LL;
    
    int a[N], ope[N], k;
    
    int Fun1(int x, int n)
    {
        n = (n+1)/2;
    
        if (x <= n) return 2*x-1;
        return (x-n)*2;
    }
    
    int Fun2(int x, int n)
    {
        return n+1-x;
    }
    
    void Solve(int x, int n)
    {
        int i, op = 0;
        LL num;
    
        for (i = k-1; i >= 0; i--)
        {
            if (ope[i] == 1) x = Fun1(x, n);
            else if (ope[i] == 2) x = Fun2(x, n);
            else op++;
        }
    
        num = x;
        for (i = 1; i <= op; i++)
            num = num * num % MOD;
    
        printf("%lld
    ", num);
    }
    
    int main ()
    {
        int T, n, m, x, i;
        char s[10];
    
        scanf("%d", &T);
    
        while (T--)
        {
            scanf("%d%d", &n, &m);
    
            k = 0;
    
            for (i = 1; i <= n; i++) a[i] = i;
    
            while (m--)
            {
                scanf("%s %d", s, &x);
    
                if (s[0] == 'O') ope[k++] = x;
                else Solve(x, n);
            }
        }
    
        return 0;
    }
  • 相关阅读:
    递归算法
    C#委托
    final 、finally
    JSP中的日期问题
    为GirdView添加CSS样式
    PC连Moto V180上网
    CSS条状图表:垂直型
    树型列表的实现
    关闭窗口无提示
    用PhotoShop做漂亮的相框,哈哈
  • 原文地址:https://www.cnblogs.com/syhandll/p/4928255.html
Copyright © 2011-2022 走看看