题意

    上下有两个位置分别对应的序列A、B,长度为n,两序列为n的一个排列。当Ai == Bj时,上下会连一条边。你可以选择序列A或者序列B进行旋转任意K步,如 3 4 1 5 2 旋转两步为 5 2 3 4 1。求旋转后最小的相交的线段的对数。

  很暴力的就做了这一题,当选择A进行旋转时,A序列翻倍,然后建一棵主席树,记录点Bi的度数,为了更新用(其实可以O(1)更新),然后长度为n的区间扫一遍。

  B亦同。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream> using namespace std; typedef long long LL;
const int maxn = *;
int n, a[maxn], b[maxn], to[maxn];
struct Tree
{
int sum[maxn*], ls[maxn*], rs[maxn*], cnt;
Tree()
{
cnt = ;
}
void pushup(int rt)
{
sum[rt] = sum[ls[rt]]+sum[rs[rt]];
}
void update(int las_rt, int rt, int l, int r, int p, int d)
{
if (l == r)
{
sum[rt] = sum[las_rt]+d;
return ;
}
int mid = (l+r)>>;
if (p <= mid)
{
ls[rt] = ++cnt, rs[rt] = rs[las_rt];
update(ls[las_rt], ls[rt], l, mid, p, d);
}
else
{
ls[rt] = ls[las_rt], rs[rt] = ++cnt;
update(rs[las_rt], rs[rt], mid+, r, p, d);
}
pushup(rt);
}
int query(int rt_1, int rt_2, int l, int r, int L, int R)
{
if (L <= l && r <= R)
return sum[rt_2]-sum[rt_1];
int mid = (l+r)>>, ret = ;
if (L <= mid)
ret += query(ls[rt_1], ls[rt_2], l, mid, L, R);
if (R > mid)
ret += query(rs[rt_1], rs[rt_2], mid+, r, L, R);
return ret;
}
}T1, T2;
int root1[maxn], root2[maxn]; int main()
{
freopen("mincross.in", "r", stdin);
freopen("mincross.out", "w", stdout);
scanf("%d", &n);
for (int i = ; i <= n; ++i)
scanf("%d", &a[i]), a[n+i] = a[i];
for (int i = ; i <= n; ++i)
scanf("%d", &b[i]), b[n+i] = b[i];
//part 1
for (int i = ; i <= n; ++i)
to[b[i]] = i;
root1[] = ++T1.cnt;
T1.update(, root1[], , n, to[a[]], );
for (int i = ; i <= *n; ++i)
{
root1[i] = ++T1.cnt;
T1.update(root1[i-], root1[i], , n, to[a[i]], );
}
LL now_sum = , ans;
for (int i = ; i <= n; ++i)
if (to[a[i]]+ <= n)
now_sum += T1.query(, root1[i], , n, to[a[i]]+, n);
ans = now_sum;
for (int i = n+; i <= *n; ++i)
{
int temp = ;
if (to[a[i]]- >= )
temp = T1.query(root1[i-n], root1[i-], , n, , to[a[i]]-);
now_sum -= temp, now_sum += (n-temp-);
ans = min(ans, now_sum);
}
//part 2
for (int i = ; i <= n; ++i)
to[a[i]] = i;
root2[] = ++T2.cnt;
T2.update(, root2[], , n, to[b[]], );
for (int i = ; i <= *n; ++i)
{
root2[i] = ++T2.cnt;
T2.update(root2[i-], root2[i], , n, to[b[i]], );
}
now_sum = ;
for (int i = ; i <= n; ++i)
if (to[b[i]]+ <= n)
now_sum += T2.query(, root2[i], , n, to[b[i]]+, n);
for (int i = n+; i <= *n; ++i)
{
int temp = ;
if (to[b[i]]- >= )
temp = T2.query(root2[i-n], root2[i-], , n, , to[b[i]]-);
now_sum -= temp, now_sum += (n-temp-);
ans = min(ans, now_sum);
}
cout <<ans <<endl;
return ;
}

USACO 2017 FEB Platinum mincross 可持久化线段树的更多相关文章

  1. USACO 2017 FEB Platinum nocross DP

    题目大意 上下有两个长度为n.位置对应的序列A.B,其中数的范围均为1~n.若abs(A[i]-B[j]) <= 4,则A[i]与B[j]间可以连一条边.现要求在边与边不相交的情况下的最大的连边 ...

  2. LOJ.6073.[2017山东一轮集训Day5]距离(可持久化线段树 树链剖分)

    题目链接 就是恶心人的,简单写写了...(似乎就是[HNOI2015]开店?) 拆式子,记\(dis_i\)为\(i\)到根节点的路径权值和,\(Ans=\sum dis_{p_i}+\sum dis ...

  3. PYOJ 44. 【HNSDFZ2016 #6】可持久化线段树

    #44. [HNSDFZ2016 #6]可持久化线段树 统计 描述 提交 自定义测试 题目描述 现有一序列 AA.您需要写一棵可持久化线段树,以实现如下操作: A v p x:对于版本v的序列,给 A ...

  4. 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1878  Solved: 846[Submit][Status ...

  5. 【BZOJ-2653】middle 可持久化线段树 + 二分

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1298  Solved: 734[Submit][Status][Discu ...

  6. HDU 4866 Shooting(持久化线段树)

    view code//第二道持久化线段树,照着别人的代码慢慢敲,还是有点不理解 #include <iostream> #include <cstdio> #include & ...

  7. 【BZOJ-3653】谈笑风生 DFS序 + 可持久化线段树

    3653: 谈笑风生 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 628  Solved: 245[Submit][Status][Discuss] ...

  8. 【BZOJ3673】&&【BZOJ3674】: 可持久化并查集 by zky 可持久化线段树

    没什么好说的. 可持久化线段树,叶子节点存放父亲信息,注意可以规定编号小的为父亲. Q:不是很清楚空间开多大,每次询问父亲操作后修改的节点个数是不确定的.. #include<bits/stdc ...

  9. 【BZOJ3207】花神的嘲讽计划I 可持久化线段树/莫队

    看到题目就可以想到hash 然后很自然的联想到可持久化权值线段树 WA:base取了偶数 这道题还可以用莫队做,比线段树快一些 可持久化线段树: #include<bits/stdc++.h&g ...

随机推荐

  1. Battery Charging Specification 1.2 中文详解 来源:www.chengxuyuans.com

    1. Introduction 1.1 Scope 规范定义了设备通过USB端口充电的检测.控制和报告机制,这些机制是USB2.0规范的扩展,用于专用 充电器(DCP).主机(SDP).hub(SDP ...

  2. 【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树

    题目传送门 题解 orz vfk的题解 3065: 带插入区间K小值 系列题解 一 二 三 四 惨 一开始用了一种空间常数很大的方法,每次重构的时候merge两颗线段树,然后无限RE(其实是MLE). ...

  3. springboot + swagger2 生成api文档

    直接贴代码: <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-sw ...

  4. [ python ] 各种推导式

    各种推导式,主要使用示例演示用法 列表生成式 示例1:求0-9每个数的平方 li = [x*x for x in range(10)] print(li) # 执行结果: # [0, 1, 4, 9, ...

  5. C#取色器

    闲来无事,就写了一个取色器.原理其实很简单,只需要两步, 获取鼠标光标的位置, 获取当前鼠标光标的位置的RGB颜色值. 获取鼠标光标的位置: System.Drawing.Point p = Mous ...

  6. 深度学习方法(十):卷积神经网络结构变化——Maxout Networks,Network In Network,Global Average Pooling

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术感兴趣的同学加入. 最近接下来几篇博文会回到神经网络结构 ...

  7. 关于Windows中的硬链接

    https://zhidao.baidu.com/question/748233720330351012.html linux中使用硬链接 ln a.txt b.txt 查看硬链接 ls -il 关于 ...

  8. 【Mac 10.13.0】安装 libimobiledevice,提示报错:warning: unable to access '/Users/lucky/.config/git/attributes': Permission denied解决方案

    打开终端,执行命令: 1.sudo chown -R XXX /usr/local  (XXX表示当前用户名) 2.ruby -e "$(curl -fsSL https://raw.git ...

  9. 【LOJ】 #2015. 「SCOI2016」妖怪

    题解 这道题教会我很多东西,虽然它是个傻逼三分 1.long double的运算常数是巨大的 2.三分之前的界要算对!一定要算准,不要想一个直接写上! 3.三分100次也就只能把精度往里推20多位,可 ...

  10. 牛客练习赛19 D-托米去购物

    最裸的最大流,没啥好说的.. #include<bits/stdc++.h> #define LL long long #define fi first #define se second ...