关闭

bzoj3744 Gty的妹子序列

标签: bzoj分块可持久化线段树树状数组
3085人阅读 评论(0) 收藏 举报
分类:

3744: Gty的妹子序列

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 967  Solved: 293
[Submit][Status][Discuss]

Description

我早已习惯你不在身边,
人间四月天 寂寞断了弦。
回望身后蓝天,
跟再见说再见……
某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现
她们排成了一个序列,每个妹子有一个美丽度。
Bakser神犇与他打算研究一下这个妹子序列,于是Bakser神犇问道:"你知道区间
[l,r]中妹子们美丽度的逆序对数吗?"
蒟蒻Autumn只会离线乱搞啊……但是Bakser神犇说道:"强制在线。"
请你帮助一下Autumn吧。
给定一个正整数序列a,对于每次询问,输出al...ar中的逆序对数,强制在线。

Input

第一行包括一个整数n(1<=n<=50000),表示数列a中的元素数。
第二行包括n个整数a1...an(ai>0,保证ai在int内)。
接下来一行包括一个整数m(1<=m<=50000),表示询问的个数。
接下来m行,每行包括2个整数l、r(1<=l<=r<=n),表示询问al...ar中的逆序
对数(若ai>aj且i<j,则为一个逆序对)。
l,r要分别异或上一次询问的答案(lastans),最开始时lastans=0。
保证涉及的所有数在int内。

Output

对每个询问,单独输出一行,表示al...ar中的逆序对数。

Sample Input

4
1 4 2 3
1
2 4

Sample Output

2

HINT

Source




分块+树状数组+可持久化线段树

如果是离线求区间逆序对数(bzoj3289),可以用莫队+树状数组解决,这道题强制在线显然不能这样做。

考虑分块,f[i][j]表示第i块的起始位置到第j个点的逆序对数,这个可以用树状数组在O(n*sqrt(n)*logn)的复杂度预处理。

然后对于每次询问,如果左右端点在同一块内,树状数组暴力计算。否则找到左端点后面第一个完整的块t,f[t][r]直接统计到答案里,前面剩余的部分,对于每一个位置i,我们要求出[i+1,r]中小于a[i]的数的个数,可以用主席树做。




#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define pa pair<int,int>
#define maxn 50005
#define maxm 1000005
using namespace std;
int n,m,tot,cnt,ans,block,T;
int a[maxn],s[maxn],num[maxn],rt[maxn],f[250][maxn];
int ls[maxm],rs[maxm],sz[maxm];
pa b[maxn];
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void add(int x,int y)
{
    for(;x<=tot;x+=(x&(-x))) s[x]+=y;
}
int sum(int x)
{
    int ret=0;
    for(;x;x-=(x&(-x))) ret+=s[x];
    return ret;
}
void insert(int x,int &y,int l,int r,int val)
{
    y=++cnt;sz[y]=sz[x]+1;
    if (l==r) return;
    ls[y]=ls[x];rs[y]=rs[x];
    int mid=(l+r)>>1;
    if (val<=mid) insert(ls[x],ls[y],l,mid,val);
    else insert(rs[x],rs[y],mid+1,r,val);
}
int getans(int x,int y,int l,int r,int L,int R)
{
    if (sz[x]==sz[y]) return 0;
    if (l==L&&r==R) return sz[y]-sz[x];
    int mid=(l+r)>>1;
    if (R<=mid) return getans(ls[x],ls[y],l,mid,L,R);
    else if (L>mid) return getans(rs[x],rs[y],mid+1,r,L,R);
    else return getans(ls[x],ls[y],l,mid,L,mid)+getans(rs[x],rs[y],mid+1,r,mid+1,R);
}
int query(int x,int y)
{
    int ret=0;
    if (num[x]==num[y])
    {
        memset(s,0,sizeof(s));
        F(i,x,y) ret+=sum(tot)-sum(a[i]),add(a[i],1);
        return ret;
    }
    ret=f[num[x]+1][y];
    F(i,x,num[x]*block) ret+=getans(rt[i],rt[y],1,tot,1,a[i]-1);
    return ret;
}
int main()
{
    n=read();
    block=round(sqrt(n));
    F(i,1,n) b[i].first=read(),b[i].second=i;
    sort(b+1,b+n+1);
    F(i,1,n)
    {
        if (i==1||b[i].first!=b[i-1].first) tot++;
        a[b[i].second]=tot;
    }
    F(i,1,n) insert(rt[i-1],rt[i],1,tot,a[i]);
    F(i,1,n) num[i]=(i-1)/block+1;
    F(i,1,num[n])
    {
        memset(s,0,sizeof(s));
        F(j,(i-1)*block+1,n)
        {
            f[i][j]=f[i][j-1]+sum(tot)-sum(a[j]);
            add(a[j],1);
        }
    }
    m=read();
    F(i,1,m)
    {
        int x=read()^ans,y=read()^ans;
        ans=query(x,y);
        printf("%d\n",ans);
    }
    return 0;
}


0
0
查看评论

BZOJ 3744 Gty的妹子序列 分块+树状数组+可持久化线段树

题目大意:给定一个序列,多次求区间内逆序对个数 强制在线 让我们呐喊一声:出题人卡常数丧心病狂! 再来一次:出题人卡常数丧心病狂!!!! 不强制在线的直接莫队就能搞 强制在线我是跪了QTZ 首先看这数据范围肯定O(n√nlogn)了  我们分块 令cnt[i][j]为从第i块的开...
  • PoPoQQQ
  • PoPoQQQ
  • 2014-11-13 23:04
  • 2637

[bzoj3787]Gty的文艺妹子序列

题目大意在线兹瓷修改操作与区间求逆序对。 所有元素大小在[1,n]很显然的离线做法我们回忆bzoj3289的做法,可以使用莫队算法,加上线段树进行兹瓷in,out,query。在线做法?我们回忆经典分块做法。 预处理ans[i,j]表示第i块到第j块的答案,sum[i,j]表示前i块元素j的个数...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2016-03-29 18:52
  • 673

[BZOJ]3744: Gty的妹子序列 分块+树状数组+主席树

分块+树状数组+主席树
  • baidu_36797646
  • baidu_36797646
  • 2017-07-16 15:57
  • 212

bzoj3809: Gty的二逼妹子序列

传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3809 思路:第一反应是莫队+树状数组,复杂度O(n^1.5*logn) TLE。。。 于是就有了一个想法,分块维护美丽度,再套一个莫队。 这样莫队移动端点就是O(1)的,每次询...
  • thy_asdf
  • thy_asdf
  • 2015-08-11 16:13
  • 452

[bzoj3744]Gty的妹子序列

题目大意在线兹瓷区间求逆序对个数。双倍经验最简单的做法是预处理ans和sum这个不用说了具体可以看根号算法题库里的经典分块思路。 当然这道题有升级版Gty的文艺妹子序列,那道题多一个修改操作。 反正我直接改了一下那题的代码交了。#include<cstdio> #include<...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2016-03-30 19:24
  • 584

bzoj3744: Gty的妹子序列

传送门 如果不强制在线的话就是莫队水题。 可是~~~ 果断分块走起。 预处理出每一个快到其他节点的逆序对个数 用数状数组实现。 前面的就用主席树。 时间复杂度O(nsqrt(n)logn)#include<cstdio> #include<cstdlib> #i...
  • zhouyuyang233
  • zhouyuyang233
  • 2017-04-06 09:09
  • 137

【bzoj3809】Gty的二逼妹子序列 莫队+分块

AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=3809 【题解】 如果没有区间[a,b]的限制,那么这题就是一道模板题。 查询答案的时候我们需要得到区间[a,b]的答案,很容易想到树状数组。 但是树状数组的时间复杂度是O(n*log...
  • chty2018
  • chty2018
  • 2016-11-29 13:47
  • 147

BZOJ 3809: Gty的二逼妹子序列|莫队算法|分块

这题还卡树状数组,一把辛酸泪啊! 考虑维护每个颜色用分块,修改是O(1)查询是sqrt(n) Code:分块#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #...
  • ws_yzy
  • ws_yzy
  • 2016-01-24 08:00
  • 341

bzoj 3809: Gty的二逼妹子序列(莫队算法+分块)

3809: Gty的二逼妹子序列 Time Limit: 80 Sec  Memory Limit: 28 MB Submit: 1059  Solved: 287 [Submit][Status][Discuss] D...
  • clover_hxy
  • clover_hxy
  • 2016-04-26 22:06
  • 274

BZOJ 3787 Gty的文艺妹子序列 分块+树状数组

题目大意:带修改、强制在线的区间逆序对 将之前3744TLE了的某个做法重写了一发 把其中一些预处理改成了树状数组 不得不说树状数组常数还是小啊 令g[i][j](i equals[i][j]表示前i块之内j的数量 这个直接暴力即可 smaller[i][j]表示前i块之内小于等于j的数的数...
  • PoPoQQQ
  • PoPoQQQ
  • 2014-12-03 17:34
  • 2019
    个人资料
    • 访问:735297次
    • 积分:11515
    • 等级:
    • 排名:第1595名
    • 原创:417篇
    • 转载:3篇
    • 译文:0篇
    • 评论:45条
    云中谁寄锦书来