zoukankan      html  css  js  c++  java
  • 【luogu P1637 三元上升子序列】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1637

    BIT + 离散化。

    读题得数据规模需离散化。BIT开不到longint这么大的数组。

    对于题目所求的三元上升子序列,我们可以通过枚举1~n作为中间数,记录左边比他小的个数L[i],右边比他大的个数R[i],那么对于第i个中间数就有L[i]*R[i]个子序列。

    L,R可以通过树状数组求得。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn = 3e4 + 10;
    int n, m, A[maxn], B[maxn], L[maxn], R[maxn];
    class BIT{
    	public:
    		int tree[maxn];
    		void update(int pos, int val)
    		{
    			while(pos <= n)
    			{
    				tree[pos] += val;
    				pos += lowbit(pos);
    			}
    		}
    		int query(int pos)
    		{
    			int res = 0;
    			while(pos)
    			{
    				res += tree[pos];
    				pos -= lowbit(pos);
    			}
    			return res;
    		}
    	private:
    		int lowbit(int x)
    		{
    			return x & -x;
    		}
    }T[2];
    int Search(int x)
    {
    	return lower_bound(B + 1, B + 1 + m, x) - B;
    }
    int main()
    {
    	cin>>n;
    	for(int i = 1; i <= n; i++)
    	{
    		cin>>A[i];
    		B[i] = A[i];
    	}
    	sort(B + 1, B + 1 + n);
    	m = unique(B + 1, B + 1 + n) - B - 1;
    	for(int i = 1; i <= n; i++)
    	A[i] = Search(A[i]);
    	for(int i = 1; i <= n; i++)
    	{
    		T[0].update(A[i], 1);
    		L[i] = T[0].query(A[i] - 1);
    	}
    	for(int i = n; i >= 1; i--)
    	{
    		T[1].update(A[i], 1);
    		R[i] = n - i - T[1].query(A[i]) + 1;
    	}
    	long long ans = 0;
    	for(int i = 2; i < n; i++) ans += L[i] * R[i];
    	cout<<ans;
    	return 0;
    }
    
    

    附:

    离散化模板:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn = 1e4 + 10;
    int n, m, A[maxn], B[maxn];
    int Search(int x)
    {
    	return lower_bound(B + 1, B + 1 + m, x) - B;
    }
    int main()
    {
    	cin>>n;
    	for(int i = 1; i <= n; i++)
    	{
    		cin>>A[i];
    		B[i] = A[i];
    	}
    	sort(B + 1, B + 1 + n);
    	m = unique(B + 1, B + 1 + n) - B - 1;
    	for(int i = 1; i <= n; i++)
    	A[i] = Search(A[i]);
    	for(int i = 1; i <= n; i++) cout<<A[i];
    }
    
  • 相关阅读:
    如何完全禁用或卸载Windows 10中的OneDrive
    ASP.NET Web API从注释生成帮助文档
    c#中使用easyUI的DataGrid组件
    第三方分页控件aspnetPager出现问题解决方法
    ActionResult派生类
    Razor引擎的转换数据类型
    ViewData与ViewBag比较
    .net开源后可以查看的源代码
    如何让一个类可以被foreach枚举?
    .NET Framework中Object基类有哪些方法?
  • 原文地址:https://www.cnblogs.com/MisakaAzusa/p/11019437.html
Copyright © 2011-2022 走看看