lojround6
花团
线段树分治裸题
给出了结束时间跟离线没区别
「LibreOJ Round #6」花火
首先在第一次使用交换是显然的
然后统计逆序对暴力是n^2的(前缀和优化)
因为交换两个点改变的只有x<i y>i
刚开始想了决策是不是单调的
然后发现不是的
我们可以将它放在图上
然后我们会发现只有左上角没有东西,右下角没有东西的点才有用
然后我们会发现这个东西满足决策单调性(很容易证明分别取两个点看一看矩形的变化就行了)
然后就是比较套路的我们要用分治算法来解决
题解用的是树状数组,也就是每层跑一次(就是bfs)
因为理论复杂度差不多然后主席树没细节就写了主席树,跑的好像挺快的啊?
时间复杂度nlog^2
#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
#define me(x) memset(x,0,sizeof(x))
#define lowbit(x) (x&(-x))
#define ll long long
const int N=4e5;
const int N2=N*;
int a[N],sum,ans,root[N],cnt,n;
#define mid ((h+t)>>1)
struct sgt{
int data[N2],ls[N2],rs[N2];
void insert(rint &x,rint lst,rint h,rint t,rint pos)
{
x=++cnt; ls[x]=ls[lst]; rs[x]=rs[lst];
data[x]=data[lst]+;
if (h==t) return;
if (pos<=mid) insert(ls[x],ls[lst],h,mid,pos);
if (pos>mid) insert(rs[x],rs[lst],mid+,t,pos);
}
int find(rint x,rint h,rint t,rint h1,rint t1)
{
if (!x) return ;
if (h1<=h&&t<=t1) return(data[x]);
rint ans=;
if (h1<=mid) ans+=find(ls[x],h,mid,h1,t1);
if (mid<t1) ans+=find(rs[x],mid+,t,h1,t1);
return ans;
}
IL int query(int x,int y,int h,int t)
{
if (x>y) return();
return(find(root[y],,n,h,t)-find(root[x-],,n,h,t));
}
}B;
int s1[N],s2[N];
void fz(int h,int t,int h1,int t1)
{
int num=-1e9,num2=;
rep(i,h1,t1)
if (s2[i]>=s1[mid])
{
rint t1=s1[mid],t2=s2[i];
rint ans2=;
if (a[t2]<a[t1])
{
// ans1=B.query(t1,t2,a[t2]+1)+t2-t1-B.query(t1,t2,a[t1]);
ans2=*B.query(t1,t2,a[t2]+,a[t1]-)+;
// ans2=t2-t1;
// ans2=2*(ans1-ans2)+1;
if (ans2>=num) num=ans2,num2=i;
}
}
sum=max(sum,num);
if (!num2) num2=h1;
if (h<=mid-) fz(h,mid-,h1,num2);
if (mid+<=t) fz(mid+,t,num2,t1);
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n;
rep(i,,n) cin>>a[i];
ll ans=;
rep(i,,n)
{
ans+=B.query(,i-,a[i]+,n);
B.insert(root[i],root[i-],,n,a[i]);
}
int cnt1=,cnt2=;
rep(i,,n) if (a[i]>=a[s1[cnt1]]) s1[++cnt1]=i;
a[]=1e9;
dep(i,n,) if (a[i]<=a[s2[cnt2]]) s2[++cnt2]=i;
reverse(s2+,s2+cnt2+);
fz(,cnt1,,cnt2);
cout<<min(ans,ans-sum+)<<endl;
return ;
}
lojround6的更多相关文章
随机推荐
- 【转】C++拷贝构造函数详解
一.什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: ; int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量. 下面看一个类对象拷贝 ...
- new-delete-malloc-free关系总结
new-delete-malloc-free关系总结 写在前面的话 这个系列的笔记总结是根据网上的两篇基础拓展而来的 C++经典面试题(最全,面中率最高) C++面试集锦( 面试被问到的问题 ) 面试 ...
- LA 6893 矩阵HASH (模板)
#include<stdio.h> #include<string.h> typedef unsigned long long ULL; ; ; int test,n,m,x, ...
- Mysql 数据库安装与配置详解
目录 一.概述 二.MySQL安装 三.安装成功验证 四.NavicatforMySQL下载及使用 一.概述 MySQL版本:5.7.17 下载地址:http://rj.baidu.com/soft/ ...
- 谓词逻辑 p->q 的真假
若p为假,则q可取真或假,p->q为永真 若p为真,q为假,则p->q为假 若p为真,q为真,则p->q为真 p q p->q 0 0 1 0 1 1 1 0 0 1 1 1 ...
- java按照关键字指定的key删除redis(支持模糊删除)
pom依赖: <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</a ...
- Truffle框架环境搭建
注意:本教程需要Truffle4.0或者是更高的版本 以太坊的智能合约只是代码,和我们的纸质代码不同,此合同需要非常精确的方式理解 如果合同编码不正确,我们的交易可能会失败,会导致gas的损失,更不用 ...
- 排查linux系统是否被入侵
在日常繁琐的运维工作中,对linux服务器进行安全检查是一个非常重要的环节.今天,分享一下如何检查linux系统是否遭受了入侵? 一.是否入侵检查 1)检查系统日志 检查系统错误登陆日志,统计IP重试 ...
- 部署apache-tomcat环境
软件体系: C/S:客户端/服务器,例如qq等app都属于C/S体系,除了编写服务端代码还需要编写客户端 优点:展现比较好,客户端会承受一点运算压力,安全性比较好 缺点:更新服务端的同时还需要更新客户 ...
- Python-Django-Ajax进阶
ajax上传文件: <h2>基于ajax上传文件</h2><p>名字 <input type="text" id="filena ...