zoukankan      html  css  js  c++  java
  • 【洛谷1637】三元上升子序列

    题面

    题目描述

    Erwin最近对一种叫"thair"的东西巨感兴趣。。。

    在含有n个整数的序列a1,a2......an中,

    三个数被称作"thair"当且仅当i< j< k且ai< aj< ak

    求一个序列中"thair"的个数。

    输入输出格式

    输入格式:

    开始一个正整数n,

    以后n个数a1~an。

    输出格式:

    "thair"的个数

    Input

    4
    2 1 3 4

    Output

    2

    Input

    5
    1 2 2 3 4

    Output

    7
    /*
    7个"thair"分别是
    1 2 3
    1 2 4
    1 2 3
    1 2 4
    1 3 4
    2 3 4
    2 3 4
    */

    说明

    约定 30%的数据n<=100
    60%的数据n<=2000
    100%的数据n<=30000
    大数据随机生成
    0<=a[i]<=maxlongint

    题解

    原来做过一道极其类似的题目
    对于任意一个选定的数aj而言
    要求的答案即是
    1~j-1中比aj小的数的个数与
    j+1~n中比aj大的数的个数
    的乘积的和
    求出数的个数可以直接使用树状数组
    最后直接统计结果就行了
    但是,考虑到N的范围很小
    但是ai< maxlongint
    因此,如果不使用离散化的话,可能会炸空间
    好了。说了这里
    直接上代码了:

    //ai在maxlongint内,不离散化数组开不下。。。 
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include<algorithm>
    using namespace std;
    #define MAX 40000
    #define INF 30000
    int n;
    inline int read()
    {
        register int x=0,t=1;
        register char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-'){t=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
        return x*t;
    }
    struct Node
    {
    	   int a;//数值 
    	   int i;//位置 
    }Q[MAX];
    bool operator <(Node a,Node b)
    {
    	   return a.a<b.a;
    }
    int c[MAX*4];
    int a[MAX],t1[MAX],t2[MAX];
    inline int lowbit(int x)
    {
    	   return x&(-x);
    }
    inline void update(int x)
    {
    	   while(x<=n)
    	   {
    	   	     c[x]+=1;
    	   	     x+=lowbit(x);
    	   }
    }
    inline int get(int x)
    {
    	   int sum=0;
    	   while(x>0)
    	   {
    	   	     sum+=c[x];
    	   	     x-=lowbit(x);
    	   }
    	   return sum;
    }
    int main()
    {
           n=read();
           for(int i=1;i<=n;++i)
              Q[i]=(Node){read(),i};
           //离散化
    	   sort(&Q[1],&Q[n+1]);
    	   for(int i=1;i<=n;++i) 
    	   {
    	   	    if(Q[i].a!=Q[i-1].a||i==1)
    	            a[Q[i].i]=i;
    	        else
    	            a[Q[i].i]=a[Q[i-1].i];
    	   }
    	   //树状数组
    	   //第一遍,求出前面所有数中,比它小的个数
    	   for(int i=1;i<=n;++i)
    	   {
    	   	      t1[i]=get(a[i]-1);
    	   	      update(a[i]);
    	   }
    	   
    	   memset(c,0,sizeof(c));
    	   
    	   //第二遍,求出后面所有数中,比它大的个数
    	   for(int i=n;i>=1;--i)
    	   {
    	   	      t2[i]=get(n-a[i]);
    	   	      update(n-a[i]+1);
    	   }
    	   
    	   //最后求和
    	   long long ans=0;
    	   for(int i=1;i<=n;++i)
    	      ans+=t1[i]*t2[i];
    	   cout<<ans<<endl;
    	   return 0; 
    }
    
    
  • 相关阅读:
    mybatis异常:org.apache.ibatis.builder.IncompleteElementException: Could not find parameter map com.sunyan.domain.User
    Markdown首行缩进和换行
    mybatis入门——mybatis的概述
    python2跟python3的区别
    码云与git
    Python入门(一)
    python环境搭建
    python简介
    计算机基础
    Typora、安装及使用
  • 原文地址:https://www.cnblogs.com/cjyyb/p/7197308.html
Copyright © 2011-2022 走看看