zoukankan      html  css  js  c++  java
  • CodeForces

    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 integers a[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: 1 l'i r'i. A query of the second type will be given in format: 2 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.

    Examples
    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
    分块+双端队列
    每次更新对每块进行操作:
    1.中间的整块:取出最后一个放入下一块的前端;
    2.两端的块:左边的块放入给定右边界位置的数字,右端的块删除给定右边界位置的数字
    每次询问:
    中间的整块直接查询,两边的块遍历可访问的位置;
      1 #include <cstdio>
      2 #include <stack>
      3 #include <cmath>
      4 #include <queue>
      5 #include <string>
      6 #include <queue>
      7 #include <cstring>
      8 #include <iostream>
      9 #include <algorithm>
     10 
     11 #define lid id<<1
     12 #define rid id<<1|1
     13 #define closein cin.tie(0)
     14 #define scac(a) scanf("%c",&a)
     15 #define scad(a) scanf("%d",&a)
     16 #define print(a) printf("%d
    ",a)
     17 #define debug printf("hello world")
     18 #define form(i,n,m) for(int i=n;i<m;i++)
     19 #define mfor(i,n,m) for(int i=n;i>m;i--)
     20 #define nfor(i,n,m) for(int i=n;i>=m;i--)
     21 #define forn(i,n,m) for(int i=n;i<=m;i++)
     22 #define scadd(a,b) scanf("%d%d",&a,&b)
     23 #define memset0(a) memset(a,0,sizeof(a))
     24 #define scaddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
     25 #define scadddd(a,b,c,d) scanf("%d%d%d%d",&a,&b,&c,&d)
     26 
     27 #define INF 0x3f3f3f3f
     28 #define maxn 100005
     29 typedef long long ll;
     30 using namespace std;
     31 //---------AC(^-^)AC---------\
     32 
     33 deque<int>::iterator it;
     34 struct node
     35 {
     36     deque<int> q;
     37     int num[maxn];
     38 }block[405];
     39 int n, m, blo, ans;
     40 int pos[maxn];
     41 
     42 void update(int a, int b)
     43 {
     44     if (pos[a] == pos[b])
     45     {
     46         it = block[pos[b]].q.begin() + ((b-1)%blo);
     47         int tmp = *it;
     48         block[pos[b]].q.erase(block[pos[b]].q.begin() + ((b-1)%blo));
     49         block[pos[b]].q.insert(block[pos[a]].q.begin() + ((a-1)%blo), tmp);
     50     }
     51     else
     52     {
     53         it = block[pos[b]].q.begin() + ((b-1)%blo);
     54         int tmp = *it;
     55         block[pos[b]].num[tmp]--;
     56         block[pos[b]].q.erase(block[pos[b]].q.begin() + ((b-1)%blo));
     57         for (int i = pos[a]; i < pos[b]; i++) {
     58             int x = block[i].q.back();
     59             block[i].q.pop_back();
     60             block[i].num[x]--;
     61             block[i + 1].q.push_front(x);
     62             block[i + 1].num[x]++;
     63         }
     64         block[pos[a]].q.insert(block[pos[a]].q.begin() + ((a-1)%blo), tmp);
     65         block[pos[a]].num[tmp]++;
     66     }
     67 }
     68 void query(int a, int b, int c)
     69 {
     70     ans=0;
     71     if (pos[a] == pos[b])
     72     {
     73         for (it = block[pos[a]].q.begin() + ((a-1)%blo); it <= block[pos[a]].q.begin() + ((b-1)%blo); it++)
     74             if ((*it) == c) ans++;
     75     }
     76     else {
     77         for (int i = pos[a] + 1; i < pos[b]; i++)    ans += block[i].num[c];
     78         for (it = block[pos[a]].q.begin() + ((a-1)%blo); it < block[pos[a]].q.end(); it++)
     79             if ((*it) == c) ans++;
     80         for (it = block[pos[b]].q.begin(); it <= block[pos[b]].q.begin() + ((b-1)%blo); it++)
     81             if ((*it) == c) ans++;
     82     }
     83     printf("%d
    ", ans);
     84 }
     85 
     86 int main()
     87 {
     88     scad(n);
     89     blo = sqrt(n);
     90     if (n%blo) blo++;
     91     forn(i, 1, n) pos[i] = (i - 1)/blo + 1;
     92 
     93     forn(i, 1, n) {
     94         int x;
     95         scad(x);
     96         int s = pos[i];
     97         block[s].q.push_back(x);
     98         block[s].num[x]++;
     99     }
    100     scad(m);
    101     ans = 0;
    102     while (m--)
    103     {
    104         int op;
    105         scad(op);
    106         if (op == 1)
    107         {
    108             int l, r;
    109             scadd(l, r);
    110             l = (l + ans - 1) % n+1;
    111             r = (r + ans - 1) % n+1;
    112             if (l > r) swap(l, r);
    113             update(l, r);
    114         }
    115         else
    116         {
    117             int l, r, k;
    118             scaddd(l, r, k);
    119             l = (l + ans - 1) % n + 1;
    120             r = (r + ans - 1) % n + 1;
    121             k = (k + ans - 1) % n + 1;
    122             if (l > r) swap(l, r);
    123             query(l, r, k);
    124         }
    125     }
    126     return 0;
    127 }
  • 相关阅读:
    css之background与第15周css补充内容叠用
    ios wkwebview didReceiveAuthenticationChallenge crash解决
    ios 版本更新提示-硬更新/软更新
    ios_UITextField-修改占位文字和光标的颜色,大小
    ios_UITextField右侧小圆叉
    ios_中将UITextField输入框设置为密码形式
    系统UISearchController详解
    iOS开发实战之搜索控制器UISearchController使用
    在iOS中如何正确的实现行间距与行高
    iOS alertController自带的输入框
  • 原文地址:https://www.cnblogs.com/mile-star/p/10484342.html
Copyright © 2011-2022 走看看