zoukankan      html  css  js  c++  java
  • Codeforces 455D

    题目链接

    D. Serega and Fun
    time limit per test
    4 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Serega loves fun. However, everyone has fun in the unique manner. Serega has fun by solving query problems. One day Fedor came up with such a problem.

    You are given an array a consisting of n positive integers and queries to it. The queries can be of two types:

    1. Make a unit cyclic shift to the right on the segment from l to r (both borders inclusive). That is rearrange elements of the array in the following manner:
      a[l], a[l + 1], ..., a[r - 1], a[r] → a[r], a[l], a[l + 1], ..., a[r - 1].
    2. Count how many numbers equal to k are on the segment from l to r (both borders inclusive).

    Fedor hurried to see Serega enjoy the problem and Serega solved it really quickly. Let's see, can you solve it?

    Input

    The first line contains integer n (1 ≤ n ≤ 105) — the number of elements of the array. The second line contains n integersa[1], a[2], ..., a[n] (1 ≤ a[i] ≤ n).

    The third line contains a single integer q (1 ≤ q ≤ 105) — the number of queries. The next q lines contain the queries.

    As you need to respond to the queries online, the queries will be encoded. A query of the first type will be given in format: l'i r'i. A query of the second type will be given in format: l'i r'i k'i. All the number in input are integer. They satisfy the constraints: 1 ≤ l'i, r'i, k'i ≤ n.

    To decode the queries from the data given in input, you need to perform the following transformations:

    li = ((l'i + lastans - 1) mod n) + 1; ri = ((r'i + lastans - 1) mod n) + 1; ki = ((k'i + lastans - 1) mod n) + 1.

    Where lastans is the last reply to the query of the 2-nd type (initially, lastans = 0). If after transformation li is greater than ri, you must swap these values.

    Output

    For each query of the 2-nd type print the answer on a single line.

    Sample test(s)
    input
    7
    6 6 2 7 4 2 5
    7
    1 3 6
    2 2 4 2
    2 2 4 7
    2 2 2 5
    1 2 6
    1 1 4
    2 1 7 3
    output
    2
    1
    0
    0
    input
    8
    8 4 2 2 7 7 8 8
    8
    1 8 8
    2 8 1 7
    1 8 1
    1 7 3
    2 8 8 3
    1 1 4
    1 2 7
    1 4 5
    output
    2 
    0

    两种操作:
    第一种是将给定区间[L, R]中最后边的数移到区间最左边。
    第二种是求给定区间[L, R]中k出现的次数。
    由于cf的空间限制比较松,而且题目的时限也不紧, 可以考虑采用平方分割的方法,
    本题用双端队列实现平方分割。。但是正规的或者效率更高的做法是使用splay。。。orz
    Accetped Code:
     1 /*************************************************************************
     2     > File Name: 445D.cpp
     3     > Author: Stomach_ache
     4     > Mail: sudaweitong@gmail.com
     5     > Created Time: 2014年08月10日 星期日 14时26分43秒
     6     > Propose: 
     7  ************************************************************************/
     8 #include <deque>
     9 #include <cmath>
    10 #include <string>
    11 #include <cstdio>
    12 #include <fstream>
    13 #include <cstring>
    14 #include <iostream>
    15 #include <algorithm>
    16 using namespace std;
    17 
    18 const int maxn = 100002;
    19 deque<int> a[355];
    20 int c[355][maxn], lastans, n, B;
    21 
    22 int deal(int x) {
    23       return (x + lastans - 1) % n + 1;
    24 }
    25 
    26 int main(void) {
    27     int t, L, R, k, x, ans, l, r, q;
    28       scanf("%d", &n); B = (int)sqrt(n+0.0);
    29     for (int i = 0; i < n; i++) {
    30         scanf("%d", &x);
    31         a[i/B].push_back(x);
    32         c[i/B][x]++;
    33     }
    34     scanf("%d", &q);
    35     lastans = 0;
    36     while (q--) {
    37         scanf("%d %d %d", &t, &L, &R);
    38         L = deal(L); R = deal(R);
    39         if (L > R) swap(L, R);
    40         L--;
    41         l = L / B, r = R / B;
    42         if (t == 2) {
    43             scanf("%d", &k);
    44             k = deal(k);
    45             ans = 0;
    46               if (l == r) {
    47                   for (int i = L%B; i < R%B; i++) ans += a[l][i]==k;
    48             } else {
    49                   for (int i = l+1; i < r; i++) ans += c[i][k];
    50                 for (int i = L%B; i < a[l].size(); i++) ans += a[l][i]==k;
    51                 for (int i = 0; i < R%B; i++) ans += a[r][i]==k;
    52             }
    53             printf("%d
    ", ans);
    54             lastans = ans;
    55         } else {
    56               if (l == r) {
    57                   x = a[l][R%B-1]; 
    58                 a[l].erase(a[l].begin()+R%B-1);
    59                 a[l].insert(a[l].begin()+L%B, x);
    60             } else {
    61                   for (int i = l; i < r; i++) {
    62                       x = a[i].back(); a[i].pop_back(); c[i][x]--;
    63                     a[i+1].push_front(x); c[i+1][x]++;
    64                 }
    65                 x = a[r][R%B]; a[r].erase(a[r].begin()+R%B); c[r][x]--;
    66                 a[l].insert(a[l].begin()+L%B, x); c[l][x]++;
    67             }
    68         }
    69     }
    70     return 0;
    71 }
     



    
    
  • 相关阅读:
    Python 绘制图表方法 收藏链接
    Python 安装 numpy 以及 matplotlib 的过程
    Project Euler 31 1000-digit Fibonacci number( DP )
    red hat 6.5 红帽企业Linux.6.5 yum This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register. 解决办法
    修改system 密码
    本地服务器 windows server 2008 datacenter conn /as sysdba 提示 ora-01031 insufficient privileges
    妙用Outlook2003群发商业邮件
    批量修改文件名称
    SQl server 2012安装问题 error code 0x858C001b 解决方法
    peoplesoft function PSTREENODE 通过 deptid 获得部门树 一级部门 名称
  • 原文地址:https://www.cnblogs.com/Stomach-ache/p/3902933.html
Copyright © 2011-2022 走看看