• HDU 5792 World is Exploding


    题意:

    给出n代表序列的长度,接下来给出序列A。找出abcd满足abcd互不相等1<=a<b<c<d<=n的同时A[a]<A[b],A[c]>A[d],问这样的abcd有几个.

    思路:先忽略四个数两两不相等的条件,那就是(,逆序对个数)乘上(顺序对个数)。例如{2,4,1,3},逆序对就是{(2,1),(4,1),(4,3)} ,顺序对就是{(2,4),(2,3),(1,3)},这样3*3=9,一共九个符合a<b && c>d的四元组。但其中有很多不合法的,对于t这个数,不合法情况的个数就是 (关于t的逆序对个数×关于t的顺序对个数),一一减去就是结果了。(不合法的规律多写几组便能找到)

    输入:

    4

    2 4 1 3

    4

    1 2 3 4

    输出:

    1
    0

    代码:

    #include <iostream>

    #include <cstdio>

    #include <cstdlib>

    #include <cmath>

    #include <vector>

    #include <queue>

    #include <cstring>

    #include <string>

    #include <algorithm>

    using namespace std;

    typedef  long long  ll;

    typedef unsigned long long ull;

    #define MM(a,b) memset(a,b,sizeof(a));

    #define inf 0x7f7f7f7f

    #define FOR(i,n) for(int i=1;i<=n;i++)

    #define CT continue;

    #define PF printf

    #define SC scanf

    const int mod=1000000007;

    const int N=1e6+10;

    int tmp[N],a[N],n,m,c[N],pos[N];

    ll lmin[N],rmin[N],lmax[N],rmax[N];

    int lowbit(int i)

    {

        return i&(-i);

    }

    void add(int x)

    {

        while(x<=m)

        {

          c[x]+=1;

          x+=lowbit(x);

        }

    }

    int query(int x)

    {

        int res=0;

        while(x>0)

        {

            res+=c[x];

            x-=lowbit(x);

        }

        return res;

    }

    int main()

    {

        while(~scanf("%d",&n))

        {

             for(int i=1;i<=n;i++)

              {

                  scanf("%d",&tmp[i]);

                  a[i]=tmp[i];

              }

             sort(tmp+1,tmp+n+1);//将tmp按从小到大排序,用于树状数组查找顺/逆序对

             m=unique(tmp+1,tmp+n+1)-tmp-1;//去重

             for(int i=1;i<=n;i++)

                 pos[i]=lower_bound(tmp+1,tmp+m+1,a[i])-tmp;//找到原来的第i个数在排序后应在的位置

             MM(c,0);

             for(int i=1;i<=n;i++)//查询0-i-1之间比a[i]小的数放在lmin[i]里,在i-m之间比a[i]大的放在lmax里

             {

                 lmin[i]=query(pos[i]-1);//

                 lmax[i]=query(m)-query(pos[i]);

                 add(pos[i]);

             }

             MM(c,0);

             for(int i=n;i>=1;i--)//逆着再来一次

             {

                 rmin[i]=query(pos[i]-1);

                 rmax[i]=query(m)-query(pos[i]);

                 add(pos[i]);

             }

             ll ans=0,l=0,r=0;

             for(int i=1;i<=n;i++)  {r+=rmax[i],l+=lmax[i];};

             ans=l*r;

             for(int i=1;i<=n;i++)//去除不合法的

             {

                 ans-=lmin[i]*rmin[i];

                 ans-=lmax[i]*rmax[i];

                 ans-=lmax[i]*lmin[i];

                 ans-=rmax[i]*rmin[i];

             }

             printf("%lld ",ans);

        }

        return 0;

    }

  • 相关阅读:
    集合类源码(六)Map(HashMap, Hashtable, LinkedHashMap, WeakHashMap)
    CycleBarrier与CountDownLatch原理
    Volatile和Synchronized
    集合类源码(五)Collection之BlockingQueue(LinkedTransferQueue, PriorityBlockingQueue, SynchronousQueue)
    集合类源码(三)Collection之List(CopyOnWriteArrayList, Stack)
    集合类源码(二)Collection之List(ArrayList, LinkedList, Vector)
    集合类源码(一)概述
    Java ReentrantLock中tryLock与lock的区别(非公平锁与公平锁)
    Arctime制作视频字幕教程
    用Pr对视频画面进行裁剪
  • 原文地址:https://www.cnblogs.com/137033036-wjl/p/5745870.html
Copyright © 2020-2023  润新知