AC日记——Little Elephant and Shifts codeforces 221e
E - Little Elephant and Shifts
思路:
一次函数线段树(疯狂debug);
b不断循环左移,判断每次最小的|i-j|,a[i]=b[j];
仔细观察发现,每个bi移动时,|i-j|呈现多个一次函数图像;
所以用线段树来维护这些一次函数图像;
线段树维护一次函数,当两个函数在区间没有交点时;
判断哪个在图像较下的位置,然后覆盖;
当有交点时,保留最优,将另一条传下去;
时间复杂度O(nlog^2n);
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; #define maxn 100005
#define INF 0x7fffffff struct TreeNodeType {
int l,r,k,b,mid; bool if_;
};
struct TreeNodeType tree[maxn<<]; int n,ai[maxn],p[maxn],X; inline void in(int &now)
{
char Cget=getchar();now=;
while(Cget>''||Cget<'') Cget=getchar();
while(Cget>=''&&Cget<='')
{
now=now*+Cget-'';
Cget=getchar();
}
} void tree_build(int now,int l,int r)
{
tree[now].l=l,tree[now].r=r,tree[now].mid=l+r>>;
if(l==r) return ;
tree_build(now<<,l,tree[now].mid);
tree_build(now<<|,tree[now].mid+,r);
} double com(int k1,int b1,int k2,int b2)
{
if(k1==k2) return ;
return (double)(b2-b1)/(double)(k1-k2);
} void tree_down(int now,int k,int b)
{
if(!tree[now].if_)
{
tree[now].if_=true,tree[now].k=k,tree[now].b=b;
return ;
}
double x=com(k,b,tree[now].k,tree[now].b);
if(x<=tree[now].l||x>=tree[now].r)
{
double mid=(double)(tree[now].l+tree[now].r)/;
if(mid*k+b<mid*tree[now].k+tree[now].b) tree[now].k=k,tree[now].b=b;
return ;
}
if(x<=tree[now].mid)
{
if(k>tree[now].k) tree_down(now<<,k,b);
else
{
tree_down(now<<,tree[now].k,tree[now].b);
tree[now].k=k,tree[now].b=b;
}
}
else
{
if(k<tree[now].k) tree_down(now<<|,k,b);
else
{
tree_down(now<<|,tree[now].k,tree[now].b);
tree[now].k=k,tree[now].b=b;
}
}
} void tree_add(int now,int l,int r,int k,int b)
{
if(tree[now].l==l&&tree[now].r==r)
{
if(tree[now].if_)
{
if(k==tree[now].k&&b==tree[now].b);
else tree_down(now,k,b);
}
else tree[now].if_=true,tree[now].k=k,tree[now].b=b;
return ;
}
if(l>tree[now].mid) tree_add(now<<|,l,r,k,b);
else if(r<=tree[now].mid) tree_add(now<<,l,r,k,b);
else
{
tree_add(now<<,l,tree[now].mid,k,b);
tree_add(now<<|,tree[now].mid+,r,k,b);
}
} void tree_query(int now,int to)
{
if(tree[now].if_) X=min(X,tree[now].k*to+tree[now].b);
if(tree[now].l==tree[now].r) return ;
if(to<=tree[now].mid) tree_query(now<<,to);
else tree_query(now<<|,to);
} int main()
{
in(n);int pos,debug;
for(int i=;i<=n;i++) in(ai[i]);
for(int i=;i<=n;i++) in(pos),p[pos]=i;
tree_build(,,n);
for(int i=;i<=n;i++)
{
if(i<p[ai[i]])
{
tree_add(,,p[ai[i]]-i+,-,p[ai[i]]+-i);
if(i!=) tree_add(,p[ai[i]]-i+,p[ai[i]],,i-p[ai[i]]-);
if(p[ai[i]]!=n) tree_add(,p[ai[i]]+,n,-,n-i+p[ai[i]]+);
}
if(i>p[ai[i]])
{
tree_add(,,p[ai[i]],,i-p[ai[i]]-);
tree_add(,p[ai[i]]+,p[ai[i]]+n-i+,-,n-i+p[ai[i]]+);
if(i-p[ai[i]]>) tree_add(,p[ai[i]]+n-i+,n,,i-n-p[ai[i]]-);
}
if(i==p[ai[i]])
{
tree_add(,,i,,-);
if(i!=n) tree_add(,i+,n,-,n+);
}
}
for(int i=;i<=n;i++) X=INF,tree_query(,i),printf("%d\n",X);
return ;
}
AC日记——Little Elephant and Shifts codeforces 221e的更多相关文章
- AC日记——Little Elephant and Array codeforces 221d
221D - Little Elephant and Array 思路: 莫队: 代码: #include <cmath> #include <cstdio> #include ...
- AC日记——Little Elephant and Numbers codeforces 221b
221B - Little Elephant and Numbers 思路: 水题: 代码: #include <cmath> #include <cstdio> #inclu ...
- AC日记——Little Elephant and Function codeforces 221a
A - Little Elephant and Function 思路: 水题: 代码: #include <cstdio> #include <iostream> using ...
- AC日记——Little Elephant and Problem codeforces 221c
221C 思路: 水题: 代码: #include <cstdio> #include <cstring> #include <iostream> #include ...
- AC日记——Sagheer and Nubian Market codeforces 812c
C - Sagheer and Nubian Market 思路: 二分: 代码: #include <bits/stdc++.h> using namespace std; #defin ...
- AC日记——Red and Blue Balls codeforces 399b
399B - Red and Blue Balls 思路: 惊讶的发现,所有的蓝球的消除都是独立的: 对于在栈中深度为i的蓝球消除需要2^i次操作: 代码: #include <cstdio&g ...
- AC日记——Andryusha and Colored Balloons codeforces 780c
C - Andryusha and Colored Balloons 思路: 水题: 代码: #include <cstdio> #include <cstring> #inc ...
- AC日记——The Child and Sequence codeforces 250D
D - The Child and Sequence 思路: 因为有区间取模操作所以没法用标记下传: 我们发现,当一个数小于要取模的值时就可以放弃: 凭借这个来减少更新线段树的次数: 来,上代码: # ...
- Codeforces Round #136 (Div. 1)C. Little Elephant and Shifts multiset
C. Little Elephant and Shifts Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/pro ...
随机推荐
- 剑指Offer - 九度1503 - 二叉搜索树与双向链表
剑指Offer - 九度1503 - 二叉搜索树与双向链表2014-02-05 23:39 题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树 ...
- Scrapy使用示例
很多网站都提供了浏览者本地的天气信息,这些信息是如何获取到的呢,方法有很多种,大多是利用某些网站提供的天气api获取的,也有利用爬虫采集的.本文就介绍如何用Scrapy来采集天气信息(从新浪天气频道采 ...
- Caliburn Micro Binding KeyDown Event
<TextBox x:Name="MyTextBox" TextAlignment="Left" FontSize="10" Widt ...
- glup自动化构建工具
实现的功能包括 js压缩,css文件合并压缩并在html加版本号,压缩html文件 1.安装gulp 建议参考官网就行http://www.gulpjs.com.cn/docs/getting-sta ...
- Python lambda介绍
在学习python的过程中,lambda的语法时常会使人感到困惑,lambda是什么,为什么要使用lambda,是不是必须使用lambda? 下面就上面的问题进行一下解答. 1.lambda是什么? ...
- DWZ(J-UI)之路:错误
1:关于左侧点击会把右边小窗口替换掉,导致右边永远只有一个小窗口. 方法:因为缺少了这个—— <li><a href="/admin/demo/index" ta ...
- KMS激活windows
slmgr /skms 106.0.6.209 slmgr /ato .查看当前系统是否永久激活,命令的作用是查看当前许可证状态的截止日期 slmgr.vbs -xpr 查看Windows正式版产品密 ...
- [转载]有关如何入门ACM
来源: 吴垠的日志 一些题外话 首先就是我为什么要写这么一篇日志.原因很简单,就是因为前几天有个想起步做ACM人很诚恳的问我该如何入门.其实就现在而言,我并不是很想和人再去讨论这样的话题,特别是当我发 ...
- hadoop2.5.2学习及实践笔记(四)—— namenode启动过程源码概览
对namenode启动时的相关操作及相关类有一个大体了解,后续深入研究时,再对本文进行补充 >实现类 HDFS启动脚本为$HADOOP_HOME/sbin/start-dfs.sh,查看star ...
- sql优化(转)
explain +sql分析sql语句执行效率 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使用! ...