1. 题目描述
有长度为$n \in [1, 10^5]$的序列,表示一个打乱的循环排列,即每当$[1 \cdots n]$中的数字全部出现后,再重新产生一个随机的覆盖$[1 \cdots n]$的序列。给定的序列并不是一个完整的循环序列,而是一个子序列。求完整的循环序列共有多少可能?

2. 基本思路
这是《算法竞赛入门经典》的原题,主要思路书里写的很清楚——利用滑动窗口确定每个位置开始是否包含一个循环节。
数据量很大,因此需要对位置进行预处理。同时,对前n个位置进行枚举,判断是否可以作为新的循环节的开始位置。滑动窗口效率很高,可以在$O(n)$时间复杂度进行预处理,算法的整体复杂度也是$O(n \times T)$的。

3. 代码

 /* 2774 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <bitset>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
#define INF 0x3f3f3f3f
#define mset(a, val) memset(a, (val), sizeof(a)) const int maxn = 1e5+;
int a[maxn];
int c[maxn];
bool valid[maxn], visit[maxn];
int n, m; void init() {
int cnt = ; memset(c, , sizeof(c));
// handle [0,n-1]
valid[] = true;
rep(i, , n) {
if (i >= m) { // n >= m
++cnt;
continue;
} if (c[a[i]] > ) {
valid[] = false;
} else {
++cnt;
} ++c[a[i]];
} for (int i=,j=n; i<m; ++i,++j) {
if (--c[a[i-]] == )
--cnt;
if (j>=m || c[a[j]]==)
++cnt;
if (j < m)
++c[a[j]]; valid[i] = cnt==n;
} // handle segment begin with i
memset(c, , sizeof(c));
visit[] = true; rep(i, , n) {
if (i>=m || c[a[i]]==) {
++c[a[i]];
visit[i+] = true;
} else {
rep(j, i+, n)
visit[j] = false;
break;
}
}
} void solve() {
init(); int ans = ; rep(i, , n) {
if (visit[i]) {
int tmp = ;
for (int j=i; j<m; j+=n) {
if (!valid[j]) {
tmp = ;
break;
}
}
ans += tmp;
} else {
break;
}
} printf("%d\n", ans);
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int t; scanf("%d", &t);
while (t--) {
scanf("%d%d",&n,&m);
rep(i, , m)
scanf("%d", &a[i]);
solve();
} #ifndef ONLINE_JUDGE
printf("time = %ldms.\n", clock());
#endif return ;
}

【HDOJ】2774 Shuffle的更多相关文章

  1. 【bzoj1965】: [Ahoi2005]SHUFFLE 洗牌 数论-快速幂-扩展欧几里得

    [bzoj1965]: [Ahoi2005]SHUFFLE 洗牌 观察发现第x张牌 当x<=n/2 x=2x 当x>n/2 x=2x-n-1 好像就是 x=2x mod (n+1)  就好 ...

  2. 【POJ】2774 Long Long Message

    [题意]给定两个字符串S和T,求最长公共子串.len<=10^5. [算法]后缀自动机 [题解]对字符串S建SAM,然后令串T在S上跑匹配. 这是自动机最原本的功能——匹配,就是串T在SAM(S ...

  3. 【HDOJ】4729 An Easy Problem for Elfness

    其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...

  4. 【HDOJ】5632 Rikka with Array

    1. 题目描述$A[i]$表示二级制表示的$i$的数字之和.求$1 \le i < j \le n$并且$A[i]>A[j]$的$(i,j)$的总对数. 2. 基本思路$n \le 10^ ...

  5. 【HDOJ】4373 Mysterious For

    1. 题目描述有两种不同类型的循环,并给出一个由1.2组成的序列,表示嵌套的循环类型.问这样组着的循环一共需要多少次循环?并将结果模364875103. 2.基本思路显然,每当遇到一个类型1的序列,即 ...

  6. 【HDOJ】1667 The Rotation Game

    1. 题目描述有个#字型的条带,可以从横线或竖线进行循环移动,求通过各种移动最终使中心的8个字符全等的长度最短并相同长度字典序最小的操作序列.2. 基本思路24个数据,8种移动方式,数据量很小了,所以 ...

  7. 【HDOJ】4374 One hundred layer

    线性DP,使用单调队列优化. /* 4374 */ #include <iostream> #include <sstream> #include <string> ...

  8. 【HDOJ】4366 Successor

    基本思路是将树形结构转换为线性结构.然后,所求即为一个区间内大于abi的最大的loy指向的ID.将结点按照abi降序排序,注意abi可能相等.然后,使用线段树单点更新,区间查询可解. /* 4366 ...

  9. 【HDOJ】4358 Boring counting

    基本思路是将树形结构转线性结构,因为查询的是从任意结点到叶子结点的路径.从而将每个查询转换成区间,表示从该结点到叶子结点的路径.离线做,按照右边界升序排序.利用树状数组区间修改.树状数组表示有K个数据 ...

随机推荐

  1. Android crop image size

    private void performCrop() { try { //call the standard crop action intent (the user device may not s ...

  2. C#加密NodeJS解密

    C#代码: class Program { static void Main(string[] args) { Console.WriteLine(", "abcdefghijkl ...

  3. 常用的机器学习&数据挖掘知识点【转】

    转自: [基础]常用的机器学习&数据挖掘知识点 Basis(基础): MSE(Mean Square Error 均方误差),LMS(LeastMean Square 最小均方),LSM(Le ...

  4. 怎么删除有外键约束的MySQL表中的数据

    SET FOREIGN_KEY_CHECKS = 0 操作结束后 SET FOREIGN_KEY_CHECKS = 1

  5. android中的selector背景选择器的用法

    关于listview和button都要改变android原来控件的背景,在网上查找了一些资料不是很全,所以现在总结一下android的selector的用法. 首先android的selector是在 ...

  6. C#: Create a WebRequest with HTTP Basic Authentication

    http://blog.csdn.net/huangyaoshifog/article/details/4470675 myReq = WebRequest.Create(url); string u ...

  7. java递归查询方法

    一.需求 项目里要让用户能够设置所选择教材的章课节,以针对章课节提供相应的题目供用户做题. 设计:用户设置了教材后,首次登录,进行章节设置时.默认为用户选择第一章.第一课.第一节. 思路:用户访问页面 ...

  8. ARRAY_SIZE宏

    宏ARRAY_SIZE,是求设备结构体中设备的个数,   定义在linux/kernel.h中   #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[ ...

  9. Maintainable HashCode and Equals Using Apache Commons

    Java hashCode and equals methods can be tricky to implement correctly. Fortunately, all majors IDEs ...

  10. UNIX command Questions Answers asked in Interview

    UNIX or Linux operating system has become default Server operating system and for whichever programm ...