zoukankan      html  css  js  c++  java
  • bzoj1145

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1145

    神题。。。。。。
    定义f(abcd)为高度排名为abcd的个数,例如闪电的个数为f(1324)。
    我们化简一下:
     f(1324)-f(1243)-f(1432)
    =f(1x2x)-f(1423)-f(12xx)+f(1234)-f(14xx)+f(1423)
    =f(1x2x)+f(1234)-f(12xx)-f(14xx)
    =f(1x2x)+f(1234)-[f(1xxx)-f(13xx)]
    =f(1x2x)+f(13xx)+f(1234)-f(1xxx)
    实验变成求f(1x2x),f(13xx),f(1234)和f(1xxx)。
    其中f(1234)和f(1xxx)都比较好求,我们来重点讨论f(1x2x)和f(13xx)。
    首先预处理出两个比较重要的数组l[i]和r[i]。l[i]表示1到i-1小于a[i]的个数;r[i]表示i+1到N中小于a[i]的个数。
    --------------------------------------------------------------------------------------------------------------------------------------------
    f(1x2x):
    我们在2的位置进行统计,不妨记2的位置为i。为方便识别,我们在位置i那里涂成红色,即f(1x2x)。
    容易发现,如果我们知道了f(132),那么f(1x2x)=f(132)*(N-i-r[i])。
    于是变成了求f(132)。
    132
    =(132+312+123+213)-(312+123+213)
    观察第1个括号:133112213
    我们发现他们左边两个黑色的数中,其中一个小于红色的数,另一个可以大于或小于红色的数。
    所以第1个括号为:l[i]*(l[i]-1)/2+l[i]*(i-1-l[i])
    观察第2个括号:3112213
    我们发现他们第2个黑色的数小于红色的数,第1个黑色的数没有限制。
    所以第2个括号为:∑(j-1)(j<i且a[j]<a[i])
    这个可以用树状数组实现。
    --------------------------------------------------------------------------------------------------------------------------------------------
    f(13xx):
    我们在3的位置进行统计,记3的位置为i,把位置i那里涂成红色,即f(13xx)。
    同样容易发现,如果我们知道了f(132),那么f(13xx)=f(132)*(N-i-r[i])。
    注意这里的f(132)和上面的f(132)的不同之处在于统计的位置(红色)。
    于是变成求f(132)。
    132
    =(132+312+321)-(312+321)
    观察第1个括号:13312 321
    我们发现3的右边一定有一个2,然后1的位置随便放。
    所以第1个括号为:∑(a[j]-1)(i<j且a[i]>a[j])
    观察第2个括号:312 321
    其实就是 3xx
    所以第2个括号为:r[i]*(r[i]-1)/2
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<fstream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<vector>
    #include<functional>
    #include<deque>
    #include<cctype>
    #include<climits>
    #include<complex>
    //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
     
    using namespace std;
    
    typedef long long LL;
    typedef double DB;
    typedef pair<int,int> PII;
    typedef complex<DB> CP;
    
    #define mmst(a,v) memset(a,v,sizeof(a))
    #define mmcy(a,b) memcpy(a,b,sizeof(a))
    #define re(i,a,b)  for(i=a;i<=b;i++)
    #define red(i,a,b) for(i=a;i>=b;i--)
    #define fi first
    #define se second
    #define m_p(a,b) make_pair(a,b)
    #define SF scanf
    #define PF printf
    #define two(k) (1<<(k))
    
    template<class T>inline T sqr(T x){return x*x;}
    template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
    template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}
    
    const DB EPS=1e-9;
    inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;}
    const DB Pi=acos(-1.0);
    
    inline int gint()
      {
            int res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    inline LL gll()
      {
          LL res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    
    const int maxN=200000;
    const LL Mod=16777216;
    
    int N;
    int a[maxN+100];
    LL l[maxN+100],r[maxN+100];
    LL ans;
    
    LL tree[maxN+100];
    #define lowbit(a) (a&(-a))
    inline void update(int a,LL v){for(;a<=N;a+=lowbit(a))tree[a]=(tree[a]+v)%Mod;}
    inline LL ask(int a){LL res=0;for(;a>=1;a-=lowbit(a))res=(res+tree[a])%Mod;return res;}
    
    LL g[maxN+100];
    
    /*
     f(1324)-f(1243)-f(1432)
    =f(1x2x)-f(1423)-f(12xx)+f(1234)-f(14xx)+f(1423)
    =f(1x2x)+f(1234)-f(12xx)-f(14xx)
    =f(1x2x)+f(1234)-[f(1xxx)-f(13xx)]
    =f(1x2x)+f(13xx)+f(1234)-f(1xxx)
    */
    
    
    int main()
      {
          freopen("bzoj1145.in","r",stdin);
          freopen("bzoj1145.out","w",stdout);
          int i;
          N=gint();
          re(i,1,N)a[i]=gint();
          mmst(tree,0);re(i,1,N)l[i]=ask(a[i]-1),update(a[i],1);
          mmst(tree,0);red(i,N,1)r[i]=ask(a[i]-1),update(a[i],1);
          ans=0;
          
          //+f(1x2x)
          re(i,1,N)g[i]=(LL(l[i])*LL(l[i]-1)/2+LL(l[i])*LL(i-1-l[i]))%Mod;
          mmst(tree,0);
          re(i,1,N)
            {
                g[i]=(g[i]-ask(a[i]-1))%Mod;
                update(a[i],i-1);
            }
          re(i,1,N)ans=(ans+g[i]*LL(N-i-r[i]))%Mod;
          
          //+f(13xx)
          mmst(tree,0);
          red(i,N,1)
            {
                LL t=LL(N-i-r[i]);
                LL p=(ask(a[i]-1)-r[i]*(r[i]-1)/2)%Mod;
                ans=(ans+p*t)%Mod;
                update(a[i],a[i]-1);
            }
             
          //+f(1234)
          re(i,1,N)g[i]=l[i];
          mmst(tree,0);re(i,1,N)update(a[i],g[i]),g[i]=ask(a[i]-1);
            mmst(tree,0);re(i,1,N)update(a[i],g[i]),g[i]=ask(a[i]-1);
            re(i,1,N)ans=(ans+g[i])%Mod;
            
            //-f(1xxx)
            re(i,1,N)
              {
                  LL t=LL(N-i-r[i]);
                  ans=(ans-t*(t-1)*(t-2)/6)%Mod;
                }
            
            ans=(ans%Mod+Mod)%Mod;
            cout<<ans<<endl;
            return 0;
        }
    View Code
  • 相关阅读:
    微信小程序之授权 wx.authorize
    微信小程序之可滚动视图容器组件 scroll-view
    纯 CSS 利用 label + input 实现选项卡
    Nuxt.js + koa2 入门
    koa2 入门(1)koa-generator 脚手架和 mongoose 使用
    vue 自定义指令
    时运赋
    WEBGL 2D游戏引擎研发系列 第一章 <新的开始>
    EasyUI特殊情况下的BUG整理
    数字时钟DigClock
  • 原文地址:https://www.cnblogs.com/maijing/p/4649491.html
Copyright © 2011-2022 走看看