CDOJ 841 权值线段树
来源:互联网 发布:原生js修改css样式 编辑:程序博客网 时间:2024/05/22 14:25
休生伤杜景死惊开
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
陆伯言军陷八卦阵之中,分明只是一条直路,却怎的也走不到尽头。阵中尽是石堆,以某一石堆为参考,无论向走还是向右,总是会回到出发的石堆,最后幸得一黄姓老翁带路才得脱出。
陆伯言逃离八卦阵后,来到山顶观察此阵,记从左往右第i堆石堆的高度为
根据石堆的情况,陆伯言大致计算了“八卦锁”的数量(即
“有劳岳父了。” “为何将其放走?” “...一表人才,何必浪费于此。”
Input
第一行一个整数
接下来一行,
Output
一个整数,“八阵锁”的数目。
Sample input and output
51 2 3 4 1
6题目大意:
显然,这道题目要求统计数列中类似“小——大——小”这样形式的数对共有多少。
解题思路:
因此,我们只要求出对于每一个数,左边比它小的树德个数ln[i],以及右边比它小的数的个数rn[i]。将ln[i]和rn[i]相乘加起来就是答案。
维护ln与rn数组,我们将运用权值线段树:
维护一个[0,32768]的线段树(见数据范围),将1~32768中的数的出现次数压入线段树。
如果询问比k小的数有多少个,求区间[1,k-1]的和(这也是为什么从0开始建树)。
因为要求ln和rn,建两棵树或初始化(博主为前者)
依次询问每个数,求出ln和rn,并维护答案。
#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<algorithm>using namespace std;#define LL long longconst int N=1000010;const int MAX=1e9+7;int n,k;struct Q{char c;int a;}q[N];int a[N],len;int ln[N],rn[N];inline void R(int &v){v=0;char ch=getchar();int f=0;while(!isdigit(ch)){if(ch=='-')f=1;ch=getchar();}while(isdigit(ch)){v=(v<<3)+(v<<1)+ch-'0';ch=getchar();}if(f) v=-v;}namespace ib {char b[100];}inline void P(int x){ if(x==0) {putchar(48); return;} if(x<0) {putchar('-'); x=-x;} char *s=ib::b; while(x) *(++s)=x%10, x/=10; while(s!=ib::b) putchar((*(s--))+48);}struct Segtree{struct trie{int l,r,len;int sum;int lz;}tree[N<<2];void updata(int o)//更新 {tree[o].sum=tree[o<<1].sum+tree[o<<1|1].sum;}void build(int o,int l,int r)//建树 {tree[o].sum=0;tree[o].l=l;tree[o].r=r;tree[o].len=r-l+1;if(l==r) {tree[o].sum=0;return;}int mid=(l+r)>>1;build(o<<1,l,mid);build(o<<1|1,mid+1,r);updata(o);}int query(int o,int ql,int qr)//区间和 {int l=tree[o].l,r=tree[o].r;if(ql<=l&&qr>=r) return tree[o].sum;int res=0;int mid=l+r>>1;if(qr<=mid) res+=query(o<<1,ql,qr);if(ql>mid) res+=query(o<<1|1,ql,qr);if(ql<=mid&&qr>mid){res+=query(o<<1,ql,mid)+query(o<<1|1,mid+1,qr);}return res;}void change(int o,int q,int v)//单点加{int l=tree[o].l,r=tree[o].r;if(l==r) {tree[o].sum+=v;return;}int mid=l+r>>1;if(q<=mid) change(o<<1,q,v);else change(o<<1|1,q,v);updata(o);}}A,B;int main(){//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);int i,j;while(scanf("%d",&n)!=EOF){for(i=1;i<=n;i++) scanf("%d",&a[i]);A.build(1,0,32768);B.build(1,0,32768);for(i=1;i<=n;i++){ln[i]=A.query(1,0,a[i]-1);A.change(1,a[i],1);}for(i=n;i>=1;i--){rn[i]=B.query(1,0,a[i]-1);B.change(1,a[i],1);}LL ans=0;for(i=1;i<=n;i++)ans+=1ll*ln[i]*rn[i];cout<<ans<<endl;}return 0;}
结语:
*权值线段树
线段树基础题型,权值的思想有点难想到,但知道以后线段树很简单。
1 0
- CDOJ 841 权值线段树
- cdoj 1259 线段树+bitset
- cdoj 母仪天下(线段树)
- 【CDOJ 383】Japan 【线段树+逆序对】
- cdoj 长使英雄泪满襟(线段树)
- CDOJ--卿学姐与基本法(线段树+离散化+区间查询)
- 【cdoj 1325】卿学姐与基本法 离散化+线段树
- 【CDOJ 1259】 昊昊爱运动Ⅱ 【bitset状压+线段树】
- CDOJ 843 冰雪奇缘 (线段树+离散)
- 【cdoj 843】冰雪奇缘 线段树保留区间
- CDOJ 1292 卿学姐种花(暴力,分块,线段树)
- CDOJ 1325 卿学姐与基本法(离散化+线段树)
- CDOJ 844 线段树区间最大连续和
- CDOJ 1324 卿学姐与公主 (分块or线段树)
- 【线段树-区间更新求区间和】CDOJ 1057
- CDOJ 1292 卿学姐种花 暴力 分块 线段树
- (CDOJ 844 线段树区间最大连续和 )<线段树的各种姿势>
- CDOJ 843 冰雪奇缘 (线段树+懒操作+离散化)
- 在CentOS安装PHP5.6
- 如何使用好log日志
- 数据结构与算法-二叉查找树(java描述)
- 【BZOJ 1969】【AHOI 2005】LANE 航线规划【离线、hash、并查集、树链剖分、线段树】
- 如何做好集成测试
- CDOJ 841 权值线段树
- 整理:用matlab创作歌曲(三)
- windows电脑系统远程公司其他电脑
- 谈高QPS下的优化
- 文章标题8
- 四、Nginx+Tomcat实现动静分离、负载均衡
- 敏捷开发实践之问题1
- C++ traits
- Mongodb启动命令mongod参数说明