http://acm.uestc.edu.cn/#/problem/show/841

休生伤杜景死惊开

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
Submit Status

陆伯言军陷八卦阵之中,分明只是一条直路,却怎的也走不到尽头。阵中尽是石堆,以某一石堆为参考,无论向走还是向右,总是会回到出发的石堆,最后幸得一黄姓老翁带路才得脱出。

陆伯言逃离八卦阵后,来到山顶观察此阵,记从左往右第i堆石堆的高度为Ai,发现任何两堆较矮的石堆都能和它们之间的一座较高的石堆形成"八卦锁",将其中之人牢牢锁住,无从逃脱。

根据石堆的情况,陆伯言大致计算了“八卦锁”的数量(即 Ai<Aj>Ak,i<j<k 的组合数),不禁心中一惊,对孔明惊为天人,遂放弃追击,收兵回吴。

“有劳岳父了。” “为何将其放走?” “...一表人才,何必浪费于此。”

Input

第一行一个整数n,表示石堆堆数。

接下来一行,n个整数,第i个数表示从左到右第i堆石堆的高度Ai。

1≤n≤50000,1≤Ai≤32768

Output

一个整数,“八阵锁”的数目。

Sample input and output

Sample Input Sample Output
5
1 2 3 4 1
6

题意:求Ai<Aj>Ak,i<j<k 的组合数。

思路:这道题目其实是求逆序数,稍作变形,可以采用线段树或者树状数组来实现。两次扫描,先从前往后扫,即插即查,每插入一次,便计算该位置之前的总数并记录,再从后往前扫,原理相同。最后求对应位置乘积和。详情见代码:

线段树实现:

 #include <fstream>
#include <iostream>
#include <cstdio>
#include <cstring> using namespace std; const int N=;
int n,m,maxn,a[N],l[N];
struct node
{
int left,right;
int sum_;
}tree[*]; void build(int id,int l,int r);//建一棵线段树
int query_sum(int id,int l,int r);//查询区间和
void update(int id,int pos);//更新位置pos的值增加1 int main()
{
//freopen("D:\\input.in","r",stdin);
//freopen("D:\\output.out","w",stdout);
long long ans=;
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]),maxn=max(a[i],maxn);
build(,,maxn);
for(int i=;i<=n;i++)
{
update(,a[i]);
l[i]=query_sum(,,a[i]-);
}
build(,,maxn);
for(int i=n;i>=;i--)
{
update(,a[i]);
ans+=l[i]*query_sum(,,a[i]-);
}
printf("%lld\n",ans);
return ;
}
void build(int id,int l,int r)
{
tree[id].left=l;
tree[id].right=r;
if(l==r)
{
tree[id].sum_=;
}
else
{
int mid=(l+r)/;
build(*id,l,mid);
build(*id+,mid+,r);
tree[id].sum_=tree[*id].sum_+tree[*id+].sum_;
}
}
int query_sum(int id,int l,int r)
{
if(l>r) return ;//注意参数的大小关系限制
if(tree[id].left==l&&tree[id].right==r)
return tree[id].sum_;
else
{
int mid=(tree[id].left+tree[id].right)/;
if(r<=mid) return query_sum(*id,l,r);
else if(l>mid) return query_sum(*id+,l,r);
else
return query_sum(*id,l,mid)+query_sum(*id+,mid+,r);
}
}
void update(int id,int pos)
{
if(tree[id].left==tree[id].right)
{
tree[id].sum_++;
}
else
{
int mid=(tree[id].left+tree[id].right)/;
if(pos<=mid) update(*id,pos);
else update(*id+,pos);
tree[id].sum_=tree[*id].sum_+tree[*id+].sum_;
}
}

树状数组实现:

 #include <fstream>
#include <iostream>
#include <cstdio>
#include <cstring> using namespace std; int n,m,maxn;
int a[],tree[],l[]; int read(int pos);//求 sum[1,pos]的答案
void update(int pos);//把a[pos]加上1 int main()
{
//freopen("D:\\input.in","r",stdin);
//freopen("D:\\output.out","w",stdout);
long long ans=;
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]),maxn=max(a[i],maxn);
for(int i=;i<=n;i++)
{
update(a[i]);
l[i]=read(a[i]-);
}
memset(tree,,sizeof(tree));
for(int i=n;i>=;i--)
{
update(a[i]);
ans+=l[i]*read(a[i]-);
}
printf("%lld\n",ans);
return ;
}
int read(int pos)
{
int ans=;
while(pos>)
{
ans+=tree[pos];
pos-=pos&(-pos);
}
return ans;
}
void update(int pos)
{
while(pos<=maxn)
{
tree[pos]++;
pos+=pos&(-pos);
}
}

cdoj841-休生伤杜景死惊开 (逆序数变形)【线段树 树状数组】的更多相关文章

  1. cdoj 841 休生伤杜景死惊开 逆序数/树状数组

    休生伤杜景死惊开 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) 陆伯言军陷八卦 ...

  2. P4315 月下“毛景树”(树链剖分)

    P4315 月下"毛景树"(树链剖分) 题面 简述: 边权转点权(在dfs1处转换) 把一条边权赋值在深度更深的上 需要实现对单边权的染色 , 路径边权的染色 , 路径边权的增加 ...

  3. 懂,你的App生,不懂,死!

    近期有一些开发人员.创业公司的人加我微信viyi88,咨询一些关于自己App的事情.被问得最多的可能就是:"我的App怎样推广添加下载量?"而且信誓旦旦地说自己的App做得非常好, ...

  4. BZOJ 1984: 月下“毛景树” [树链剖分 边权]

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1728  Solved: 531[Submit][Status][Discu ...

  5. 【BZOJ1984】月下“毛景树” 树链剖分+线段树

    [BZOJ1984]月下"毛景树" Description 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校 ...

  6. 【BZOJ-1984】月下“毛景树” 树链剖分

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1314  Solved: 416[Submit][Status][Discu ...

  7. Bzoj 1984: 月下“毛景树” 树链剖分

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1282  Solved: 410[Submit][Status][Discu ...

  8. 树剖+线段树||树链剖分||BZOJ1984||Luogu4315||月下“毛景树”

    题面:月下“毛景树” 题解:是道很裸的树剖,但处理的细节有点多(其实是自己线段树没学好).用一个Dfs把边权下移到点权,用E数组记录哪些边被用到了:前三个更新的操作都可以合并起来,可以发现a到b节点间 ...

  9. P4315 月下“毛景树”[树剖]

    题目描述 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬毛毛虫爬到了一颗小小的"毛景树&quo ...

随机推荐

  1. 神奇的null和undefined

    在JavaScript中,有两个特殊的类型存在,它们都只有一个值,分别null和undefined,之所以将它们放在一块,是因为在使用方面它们有很多相似之处. 相同点 在JavaScript中,nul ...

  2. sikuli 安装

    1     简介 官方介绍: Sikuli脚本自动化,你在屏幕上看到的任何东西.它使用图像识别,识别和控制GUI组件.这是有用的,当有一个GUI的内部或源代码的访问是不容易的. Sikuli(在墨西哥 ...

  3. LINK : fatal error LNK1158: 无法运行“rc.exe”解决办法 and Visual Studio 2017 下载安装

    LINK : fatal error LNK1158: 无法运行“rc.exe” 首先下载软件包:https://pan.baidu.com/s/1L1N1sikXUaZZd-9nmZnwjA 第一个 ...

  4. 【Gearman学习笔记】分布式处理入门

    1.首先,确保你已经安装了gearmand环境并且语言绑定(language binding)已经生效. 2.涉及到的各个部分: ServerThe server, gearmand, will co ...

  5. centos自带的dvd中的官方base源,丢失了可以复制下面的内容

    /etc/yum.repos.d/CentOS-Base.repo文件中的内容,同样适用于centos6 [base]name=CentOS-$releasever - Basemirrorlist= ...

  6. 新手搭建 nginx + php (LNMP)

    配置源 纯净的Centos 6.5系统 配置163yum源 (这个比较简单,百度能解决很多问题) 开始 安装  开发软件包:yum  -y groupinstall  "Developmen ...

  7. js的数组操作相关(BigTree*)

    JavaScript中创建数组有两种方式 (一)使用 Array 构造函数: var arr1 = new Array(); //创建一个空数组var arr2 = new Array(20); // ...

  8. pycharm下getpass.getpass()卡住

    pycharm下getpass.getpass()卡住不运行是什么问题 python pycharm 首先声明 下面这几行代码在命令行和eclipse下都能正常运行 import getpass pr ...

  9. 利用Win10计划任务 + 弹窗,提醒你自己

    博主公司周报漏交一次要缴纳50RMB部门经费,另外博主每天上午下午都需要活动10分钟(好像放风..),防止职业病 + 让自己的工作状态更好. 步骤: 1.打开Win10控制面板 —> 点选管理工 ...

  10. Vuex以及axios 看这个

      vuex  -- 安装   npm i vuex  -- 配置   -- 导入vuex      import vuex from "vuex"   -- vue使用vuex  ...