码迷,mamicode.com
首页 > 编程语言 > 详细

【XSY2714】大佬的难题 数学 树状数组

时间:2018-03-06 12:03:33      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:排列   amp   str   stdout   isp   string   online   void   题目   

题目描述

  给你三个排列\(A,B,C\),求
\[ \sum_{1\leq x,y\leq n}[a_x<a_y][b_x<b_y][c_x<c_y] \]
  \(n\leq 2\times {10}^6\)

题解

  就是一个三位偏序。用CDQ分治可以做到\(O(n\log^2 n)\)常熟小一点可以卡过。我在UOJ上面能跑过去。

  这道题只有一个特殊性质:\(A,B,C\)都是排列。

  我们记
\[ \begin{align} K_{x,y}&=[a_x<a_y]+[b_x<b_y]+[c_x<c_y]\S_{x,y}&=\max(K_{x,y},K_{y,x})\A&=\sum_{1\leq x\leq y\leq n}[S_{x,y}=3]\B&=\sum_{1\leq x\leq y\leq n}[S_{x,y}=2]\P_{a,b}&=\sum_{1\leq x,y\leq n}[a_x<a_y][b_x<b_y]\P_{a,c}&=\sum_{1\leq x,y\leq n}[a_x<a_y][c_x<c_y]\P_{b,c}&=\sum_{1\leq x,y\leq n}[b_x<b_y][c_x<c_y]\\end{align} \]
  那么我们要求的答案就是\(A\)了。

  容易发现
\[ \begin{align} A+B&=\binom{n}{2}\3A+B&=P_{a,b}+P_{a,c}+P_{b,c} \end{align} \]
  原问题转化为二位偏序。

  用树状数组即可解决。

  时间复杂度:\(O(n\log n)\)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<utility>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
ll seed;
ll rd()
{
    return seed=((seed*19260817)^233333)&((1<<24)-1);
}
int n;
void gen(int *a)
{
    int i;
    for(i=1;i<=n;i++)
        a[i]=i;
    for(i=1;i<=n;i++)
        swap(a[i],a[rd()%i+1]);
}
int a1[2000010];
int a2[2000010];
int a3[2000010];
int a[2000010];
int c[2000010];
void add(int x)
{
    for(;x<=n;x+=x&-x)
        c[x]++;
}
int sum(int x)
{
    int s=0;
    for(;x;x-=x&-x)
        s+=c[x];
    return s;
}
ll gao(int *a1,int *a2)
{
    memset(c,0,sizeof c);
    int i;
    for(i=1;i<=n;i++)
        a[a1[i]]=a2[i];
    ll s=0;
    for(i=1;i<=n;i++)
    {
        s+=sum(a[i]);
        add(a[i]);
    }
    return s;
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
#endif
    scanf("%d",&n);
    scanf("%lld",&seed);
    gen(a1);
    scanf("%lld",&seed);
    gen(a2);
    scanf("%lld",&seed);
    gen(a3);
    ll ans=0;
    ans+=gao(a1,a2);
    ans+=gao(a1,a3);
    ans+=gao(a2,a3);
    ans-=ll(n-1)*n/2;
    ans/=2;
    printf("%lld\n",ans);
    return 0;
}

【XSY2714】大佬的难题 数学 树状数组

标签:排列   amp   str   stdout   isp   string   online   void   题目   

原文地址:https://www.cnblogs.com/ywwyww/p/8513559.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!