51nod 1471 小S的兴趣 sqrt

小S喜欢有趣的事。但是,每个人的兴趣都是独特的。小S热衷于自问自答。有一天,小S想出了一个问题。

有一个包含n个正整数的数组a和针对这个数组的几个问题。这些问题有两种类型:

1.      在数组下标l到r的部分上,将一个单元格循环移动到右端。即以下面方式重新分配数组上的元素。

a[l], a[l+1], ..., a[r-1], a[r] → a[r], a[l], a[l+1], ..., a[r-1].

2.      在数组下标l到r的部分上,计算有多少元素的值与k相等。

小S很喜欢这个问题并且很快解决了它,你是否能够解决它呢?

分块,每一个块维护一个链表,也可以用数组模拟,不包含整个区间就暴力更改。

O(nsqrt(n))

右移相当于在末尾删除一个元素,在首部添加一个元素。

debug了很久,原因:在解密l,r,k,后,有可能l > r,这个时候要swap(l,r)

代码:

  //File Name: nod1471.cpp
  //Author: long
  //Mail: [email protected]
  //Created Time: 2016年09月15日 星期四 21时17分30秒

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <map>
#define LL long long
using namespace std;
const int MAXN = 100000 + 10;
const int NUM = 400;
int l[MAXN/NUM+5],r[MAXN/NUM+5],belong[MAXN];
int a[MAXN],tmp[NUM],cnt;
struct Block{
    int b[NUM],s[MAXN],head,tot;
    void build(const int l,const int r){
        tot = head = 0;
        memset(s,0,sizeof s);
        for(int i=l;i<=r;i++){
            b[tot++] = a[i];
            s[a[i]]++;
        }
    }
    void right(int st){
        head--;
        if(head < 0) head = tot - 1;
        cnt = b[head];
        s[cnt]--;
        b[head] = st;
        s[st]++;
    }
    void reset(){
        if(head == 0) return ;
        for(int i=0;i<tot;i++) tmp[i] = b[i];
        int u = 0;
        for(int i=head;i<tot;i++) b[u++] = tmp[i];
        for(int i=0;i<head;i++) b[u++] = tmp[i];
        head = 0;
    }
    void brute(int st,int l,int r){
        reset();
        cnt = b[r];
        s[cnt]--;
        for(int i=r;i>l;i--) b[i] = b[i-1];
        b[l] = st;
        s[st]++;
    }
    int get(int k){
        k = (head + k) % tot;
        return b[k];
    }
    int query(int k){
        return s[k];
    }
    int cal(int l,int r,int k){
        reset();
        int res = 0;
        for(int i=l;i<=r;i++)
            if(b[i] == k) res++;
        return res;
    }
}block[MAXN / NUM + 5];
void solve(int n){
    for(int i=1;i<=n;i++)
        belong[i] = (i - 1) / NUM;
    int tot = belong[n] + 1,u=1;
    for(int i=0;i<tot;i++,u+=NUM){
        l[i] = u;
        r[i] = min(u + NUM - 1,n);
    }
    for(int i=0;i<tot;i++)
        block[i].build(l[i],r[i]);
    int ans = 0,q,op,x,y,k;
    scanf("%d",&q);
    while(q--){
        scanf("%d %d %d",&op,&x,&y);
        if(op == 1){
            x = (x + ans - 1) % n + 1;
            y = (y + ans - 1) % n + 1;
            if(x > y) swap(x,y);
            int bx = belong[x],by = belong[y];
            if(bx == by){
                cnt = block[bx].get(y-l[bx]);
                block[bx].brute(cnt,x-l[bx],y-l[bx]);
            }
            else{
                cnt = block[by].get(y-l[by]);
                block[bx].brute(cnt,x-l[bx],r[bx]-l[bx]);
                for(int i=bx+1;i<by;i++)
                    block[i].right(cnt);
                block[by].brute(cnt,0,y-l[by]);
            }
        }
        else{
            scanf("%d",&k);
            x = (x + ans - 1) % n + 1;
            y = (y + ans - 1) % n + 1;
            k = (k + ans - 1) % n + 1;
            if(x > y) swap(x,y);
            //cout << x << " " << y << " " << k << " " << endl;
            int bx = belong[x],by = belong[y];
            ans = 0;
            if(bx == by)
                ans = block[bx].cal(x-l[bx],y-l[bx],k);
            else{
                ans += block[bx].cal(x-l[bx],r[bx]-l[bx],k);
                for(int i=bx+1;i<by;i++)
                    ans += block[i].query(k);
                ans += block[by].cal(0,y-l[by],k);
            }
            printf("%d\n",ans);
        }
    }
}
int main(){
    int n;
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++) scanf("%d",a + i);
        solve(n);
    }
    return 0;
}
时间: 2024-10-13 22:23:49

51nod 1471 小S的兴趣 sqrt的相关文章

51nod1471 小S的兴趣

题目来源: CodeForces 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 320 小S喜欢有趣的事.但是,每个人的兴趣都是独特的.小S热衷于自问自答.有一天,小S想出了一个问题. 有一个包含n个正整数的数组a和针对这个数组的几个问题.这些问题有两种类型: 1.      在数组下标l到r的部分上,将一个单元格循环移动到右端.即以下面方式重新分配数组上的元素. a[l], a[l+1], ..., a[r-1], a[r] → a[r], a[l], a[l+1], ...

51nod 1631 小鲨鱼在51nod小学

基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 鲨鱼巨巨2.0(以下简称小鲨鱼)以优异的成绩考入了51nod小学.并依靠算法方面的特长,在班里担任了许多职务. 每一个职务都有一个起始时间A和结束时间B,意为小鲨鱼在[A, B]时间内,担任了某职务(inclusively). 现在给定小鲨鱼的职务履历表,你可以高效的给出小鲨鱼在某天担任了哪些职务吗? p.s. 由于小鲨鱼担任的职务太多,所有任期小于一个自然月的职务都忽略不计.(如1月1日~2月1日为一个自然月,

51nod 1831 小C的游戏

小C和小L是好朋友,她们在玩一个游戏. 一开始有一个大小为n的石子堆,小C先手. 每次可以对这个石子堆拿走一个或者把这个石子堆分成等量的几份并只取其中一份(不能不变或只剩下一个). 如果取走最后一个人的算败,请问这个游戏小C是否能胜. Input一行表示数据组数Tcases(Tcases<=1,000). 后面Tcases行每行一个n(n<=1,000,000,000).Output有Tcases行对于先手获胜输出“TAK”,先手狗带输出“NIE”.Sample Input 1 5 Sampl

51nod 2485 小b重排字符串

小b有一个字符串S,现在她希望重排列S,使得S中相邻字符不同. 请你判断小b是否可能成功. 样例解释:将"aab"重排为"aba"即可. 收起 输入 输入一个只包含小写字母的字符串S,其长度n满足1≤n≤500 输出 如果可能,输出"Possible": 否则,输出"Impossible". 输入样例 aab 输出样例 Possible 只要同一种字母不超过总数的一半即可,保证能交叉放开.代码: #include <io

51nod 1643 小Q的家庭作业

题意: f(n) = sigma(gcd(i,n))  1 <= i <= n g(n) = sigma(f(d))    d | n n = x1 * x2 * ... * xm 其中 x[i+1] = (a * x[i] + b) % c + 1 1 <= m <= 10^18 1 <= c <= 10^7 1 <= x[1],a,b  <= c 首先,发现f,g函数都是积性函数 并且推下公式:g[n] = n * (k1 + 1 ) * (k2 + 1

51nod 1831 小C的游戏(博弈论+打表)

比较坑的题目. 题意就是:给出一堆石子,一次操作可以变成它的约数个,也可以拿只拿一个,不能变成一个,最后拿的人输. 经过打表发现 几乎所有质数都是先手必败的,几乎所有合数都是先手必胜的 只有几个例外,就是17^n, 2^n这些. 不过继续推导可以发现16是先手必败的,因为2,4,8,15都是先手必胜的 所以2^n(n>4)都是先手必胜的 17是先手必胜的,所以17^2是先手必败的,17^n(n>2)是先手必胜的 17*2是先手必败的 同理可以推导出2^n*17^m这些(当n>1或m>

51nod 1804 小C的多边形(构造)

首先可以算出无解的充分不必要条件,所有边的和为sum=3*((n-1)*n)/2,如果sum%n!=0显然无解. 也就是说n为奇数必然无解.现在考虑n为偶数的情况. 不妨假设n为偶数有解,现在考虑如何将这个解构造出来. 设此时n边形的为2*k+1,那么也就说,内边的每相邻两个边的和要为{k+2....3*k+2} 把边构造成这个样子即可. k+1 1 k+2 2 k+3......2*k+1. 另外这个oj的读入效率真是感人肺腑啊... # include <cstdio> # include

51nod——2476 小b和序列 预处理

对于每一个元素,预处理出它作为最小值,两边可以作用到的最大位置.比如下标∈[0,8]的这个数组:1 8 6 2 5 4 3 8 7,1可以作用到所有区间,2可以作用到区间[1,8],第一个8可以作用到[1,7].也就是说从两边分别找到第一个大于等于这个元素的位置,然后标记,其实就是找最宽的区间长度.可能左边更宽也可能右边更宽,对所有元素的max(a[i]*(i-l[i])),a[i]*(r[i]-i)) 求max就是答案了. 1 #include <bits/stdc++.h> 2 using

对于公司中的小团体该怎么处理?

在很多公司中,都会存在一些小的团体,他们或以相同的兴趣或者住在一起而聚集再一起,对于不同阶段的公司,这些小团体,对于公司都是有一些影响.很多公司比较支持员工以兴趣为方向组成兴趣小组,然后开展相关的一些活动.增进员工之间的了解.但是更多的公司是比较忌惮公司内部的一些小团体,特别是涉及利益而促成的一些小团体.那么从公司的角度来看,对于这些小团体有什么影响. 首页积极的一面.公司内存存在的一些小的以兴趣为方向而形成的一些小团体.增加了公司的凝聚性,增进了公司员工之间的了解,对于工作的开展提供了较多的方