题意:编号1-n的小朋友依次围成一圈,给定目标状态每个小朋友左右两边的小朋友编号,每次可以选择编号为[b1,b2,...,bm]的小朋友,作1次轮换,bi是任意编号,代价为m。求变成目标状态所需的最小代价。

思路:有置换的知识,任意一个置换可以写成若干循环的乘积,那么每次选择一个大小大于1的循环,把这个循环变成目标状态,代价为循环的大小。那么要使总代价最小,就要使得大小大于1的循环的大小和最小,也就是大小为1的循环的个数尽量多,也就是把目标状态和原状态进行比较,使得对应位置相等的点最多。现在来求这个最大值,由于目标状态是个环,起点有n个,有2个方向,所以总共2n种不同状态,但是状态之间是有联系的。先考虑一个方向,预处理出某个状态与原状态对应位上的差,此时的答案就是差为0的个数,当起点变为下一个时,后n-1个位(或前n-1个位)的差全部变化为1,剩下的一位特殊处理。于是可以设计一个这样的数据结构,用一个mark标记表示当前区间整体变化了多少,cnt[i+mark]就表示当前值为i的个数,每次取cnt[mark]得到差为0的个数,更新时也通过mark标记定位到正确地址。复杂度O(n)。

  1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#pragma comment(linker, "/STACK:10240000")
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; #define X first
#define Y second
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define copy(a, b) memcpy(a, b, sizeof(a)) typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull; #ifndef ONLINE_JUDGE
void RI(vector<int>&a,int n){a.resize(n);for(int i=;i<n;i++)scanf("%d",&a[i]);}
void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?:-;
while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
void print(T*p, T*q){int d=p<q?:-;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
#endif
template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);} const double PI = acos(-1.0);
const int INF = 1e9 + ;
const double EPS = 1e-12; /* -------------------------------------------------------------------------------- */ const int maxn = 2e5 + ; struct Node {
int a[maxn * ];
int &operator [] (int x) {
return a[x + maxn];
}
}; int l[maxn], r[maxn], b[maxn], c[maxn];
Node cnt;
bool vis[maxn]; int f(int id2, int id1) {
return l[id1] == id2? r[id1] : l[id1];
} int work(int a[], int n) {
fillchar(cnt.a, );
for (int i = ; i <= n; i ++) {
cnt[i - a[i]] ++;
}
int ans = cnt[], mark = ;
for (int i = ; i < n; i ++) {
mark ++;
cnt[i - a[i] + mark] --;
cnt[n - a[i] + mark] ++;
umax(ans, cnt[mark]);
}
return ans;
} int main() {
//#ifndef ONLINE_JUDGE
// freopen("in.txt", "r", stdin);
// //freopen("out.txt", "w", stdout);
//#endif // ONLINE_JUDGE
int n;
cin >> n;
for (int i = ; i <= n; i ++) {
scanf("%d%d", l + i, r + i);
}
b[] = c[] = ;
b[] = l[];
c[] = r[];
vis[] = vis[l[]] = true;
for (int i = ; i <= n; i ++) {
b[i] = f(b[i - ], b[i - ]);
c[i] = f(c[i - ], c[i - ]);
vis[b[i]] = true;
}
for (int i = ; i <= n; i ++) {
if (!vis[i]) {
puts("-1");
return ;
}
}
int ans = ;
umax(ans, work(b, n));
umax(ans, work(c, n));
cout << n - ans << endl;
return ;
}

[vijos P1008 篝火晚会]置换的更多相关文章

  1. NOIP2005 篝火晚会 解题报告

    佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了“小教官”.在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会.一共有n个同学,编号从1到n.一开始,同学们按照1,2,… ...

  2. NOIP2005 篝火晚会

    篝火晚会 (fire.pas/c/cpp) [问题描述] 佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了“小教官”.在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会. ...

  3. [NOIP 2005]-- 篝火晚会

    额~~,对这组题感兴趣的具体的解题报告可以戳戳这里:http://wenku.baidu.com/view/878beb64783e0912a2162aa7.html?qq-pf-to=pcqq.c2 ...

  4. 洛谷 P1053 篝火晚会 解题报告

    P1053 篝火晚会 题目描述 佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了"小教官".在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会.一共有 ...

  5. [LuoguP1053][Noip2005]篝火晚会

    [LuoguP1053][Noip2005]篝火晚会(Link) 现在你有一个排成一个圈的\(N\)大小的队列,一开始的顺序是\(\{1,2,3,4...N\}\),一共有\(N\)个要求,第\(i\ ...

  6. P1053 篝火晚会

    题目描述 佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了“小教官”.在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会.一共有nnn个同学,编号从111到nnn.一开始 ...

  7. 洛谷P1053 篝火晚会

    P1053 篝火晚会 题目描述 佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了“小教官”.在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会.一共有n个同学,编号从1到 ...

  8. 「NOIP2005」「Codevs1106」篝火晚会

    题目描述 Description 佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了“小教官”.在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会.一共有n个同学,编号从1 ...

  9. [NOIP2005] 提高组 洛谷P1053 篝火晚会

    题目描述 佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了“小教官”.在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会.一共有n个同学,编号从1到n.一开始,同学们按照 ...

随机推荐

  1. asp.net core web api + Element-UI的Vue管理后台

    后端:asp.net core web api + EF Core 前端:VUE + Element-UI+ Node环境的后台管理系统. 线上地址:http://www.wangjk.wang/ 密 ...

  2. linux CVE-2019-14287 Sudo提权漏洞

    CVE-2019-14287 sudo介绍 sudo,也就是以超级管理员身份运行(superuser do)的意思.sudo 是 Linux 中最常使用的重要实用程序之一,它功能十分强大,几乎安装在每 ...

  3. 堆溢出---glibc malloc

    成功从来没有捷径.如果你只关注CVE/NVD的动态以及google专家泄露的POC,那你只是一个脚本小子.能够自己写有效POC,那就证明你已经是一名安全专家了.今天我需要复习一下glibc中内存的相关 ...

  4. 面试官:你对Redis缓存了解吗?面对这11道面试题你是否有很多问号?

    前言 关于Redis的知识,总结了一个脑图分享给大家 1.在项目中缓存是如何使用的?为什么要用缓存?缓存使用不当会造成什么后果? 面试官心理分析 这个问题,互联网公司必问,要是一个人连缓存都不太清楚, ...

  5. (转)如何学好C语言

    原文:http://coolshell.cn/articles/4102.html    作者:陈皓 有人在酷壳的留言版上询问下面的问题 keep_walker : 今天晚上我看到这篇文章. http ...

  6. js 函数对象的继承 inherit 带 插件完整解析版[helpers.js]

    前言:         本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽.         本篇文章为您分析一下原生JS的对象继承方法 需求分析: 1. ...

  7. IDEA 之 ERROR:无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core]

    问题描述:在使用IDEA对JSTL进行测试时出现error:无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core] ...

  8. Floyd-Warshall算法正确性证明

    以下所有讨论,都是基于有向无负权回路的图上的.因为这一性质,任何最短路径都不会含有环,所以也不讨论路径中包含环的情形!并且为避免混淆,将"最短路径"称为权值最小的路径,将路径经过的 ...

  9. Spring Boot 整合 Spring Security,用户登录慢

    场景 Spring Boot + Spring Security搭建一个Web项目. 临时用了inMemoryAuthentication. @EnableWebSecurity public cla ...

  10. linux rpm包

    rpm包,软件包,程序包,以.rpm结尾的包 我们刚开始安装的Linux系统是最小化安装(minimol),只安装系统,不安装不必要的软件包 刚开始vim,ifconfig,tree等命令都没有,当然 ...