zoukankan      html  css  js  c++  java
  • 「LGR-049」洛谷7月月赛 D.Beautiful Pair

    [「LGR-049」洛谷7月月赛 D.Beautiful Pair](https://www.luogu.org/problemnew/show/P4755)

    题目大意 : 给出长度为 (n) 的序列,求满足 (i leq j) 且 $a_i imes a_j leq max(a_i..a_j) $ 的点对((i, j))的数量
    (n leq 10^5 1 leq a_i leq 10^9)

    解题思路 :

    直接枚举某一端点貌似很难维护极值,不妨对于每一个极值 (a_k),求 $ max(a_i..a_j) leq a_k$ 且 (i leq k leq j) 的点对数
    考虑一个每一个点能作为(max)统治的区间可以用单调栈求,并构建出笛卡尔树

    此时对于每一个 (a_k) 答案由两部分产生:

    1. 点对 ((i, j)) 满足 (i = k) 或 $j = k $,这一部分答案比较简单,就是统治区间内 (1) 的个数
    2. 点对 ((i, j)) 满足 (i eq k)(j eq k) ,此时答案等价于点 (k) 在笛卡尔树上的节点的左右子树中各取一个组成合法点对的方案数

    第一种情况可以直接前缀和计算,在此不多做讨论,主要看第二种情况

    由于是树上的子树问题,我们很容易想到用 (dsu on tree) 的做法来解决

    不了解 (dsu on tree) 的可以戳这里的链接

    枚举子树大小较小的子树,用树状数组维护较大的子树产生的贡献

    对于较小子树中的点 (u) ,能与其组成合法点对的点 (x) 要满足 (frac{maxval}{a_u} leq a_x),直接用树状数组统计前缀和即可


    /*program by mangoyang*/
    #include<bits/stdc++.h>
    #define inf (0x7f7f7f7f)
    #define Max(a, b) ((a) > (b) ? (a) : (b))
    #define Min(a, b) ((a) < (b) ? (a) : (b))
    typedef long long ll;
    using namespace std;
    template <class T>
    inline void read(T &x){
        int f = 0, ch = 0; x = 0;
        for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
        for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
        if(f) x = -x;
    }
    #define N (500005)
    #define int ll
    int a[N], b[N], n, ans;
    namespace Ls{
    	int s[N]; int lens = 0;
    	inline int calc(int x){
    		int res = upper_bound(s + 1, s + lens + 1, x) - s - 1;
    		return res;
    	}
    	inline void Realmain(){
    		for(int i = 1; i <= n; i++) s[i] = a[i];
    		sort(s + 1, s + n + 1);
    		lens = unique(s + 1, s + n + 1) - s - 1;
    	}
    }
    struct Fenwick{
    	int s[N];
    	inline int lowbit(int x){ return x & -x; }
    	inline void add(int x, int v){
    		for(int i = x; i <= n; i += lowbit(i)) s[i] += v;
    	}
    	inline int query(int x){
    		int ans = 0;
    		for(int i = x; i; i -= lowbit(i)) ans += s[i];
    		return ans;
    	}
    }Bit;
    namespace Treap{
    	int sz[N], ch[N][2], s[N], l[N], r[N], st[N], top;
    	inline void Getsize(int u){
    		sz[u] = 1; 
    		int ls = ch[u][0], rs = ch[u][1];
    		if(ls) Getsize(ls), sz[u] += sz[ls];
    		if(rs) Getsize(rs), sz[u] += sz[rs];
    		if(!u) sz[u] = 0;
    	}
    	inline void Add(int u){
    		Bit.add(b[u], 1);
    		if(ch[u][0]) Add(ch[u][0]);
    		if(ch[u][1]) Add(ch[u][1]);
    	}
    	inline void Clear(int u){
    		Bit.add(b[u], -1);
    		if(ch[u][0]) Clear(ch[u][0]);
    		if(ch[u][1]) Clear(ch[u][1]);
    	}
    	inline int Count(int u, int val){
    		int pos = Ls::calc(val / a[u]);
    		int res = Bit.query(pos);
    		if(ch[u][0]) res += Count(ch[u][0], val);
    		if(ch[u][1]) res += Count(ch[u][1], val);
    		return res;
    	}
    	inline void solve(int u){
    		int p = sz[ch[u][0]] > sz[ch[u][1]] ? 0 : 1;
    		int ms = ch[u][p], ls = ch[u][p^1];
    		if(ls) solve(ls), Clear(ls);
    		if(ms) solve(ms); 
    		if(ls) ans += Count(ls, a[u]);
    		if(u){ if(ls) Add(ls); Bit.add(b[u], 1); } 
    	}
    	inline void Build(){
    		for(int i = 1; i <= n; i++){
    			while(a[st[top]] <= a[i] && top) r[st[top--]] = i - 1;
    			int f = st[top]; l[i] = f + 1;
    			ch[i][0] = ch[f][1], ch[f][1] = i, st[++top] = i; 
    		}
    		for(int i = 1; i <= n; i++) if(!r[i]) r[i] = n;
    	}
    	inline void Realmain(){
    		Build(), Getsize(0), solve(0);
    		for(int i = 1; i <= n; i++) s[i] = s[i-1] + (a[i] == 1 ? 1 : 0);
    		for(int i = 1; i <= n; i++) ans += s[r[i]] - s[l[i]-1];
    		cout << ans << endl;
    	}
    }
    main(){
    	read(n);
    	for(int i = 1; i <= n; i++) read(a[i]);
    	Ls::Realmain();
    	for(int i = 1; i <= n; i++) b[i] = Ls::calc(a[i]);
    	Treap::Realmain();
    	return 0;
    }
    
    
  • 相关阅读:
    什么是重名问题,树型目录结构如何解决这一问题。
    什么是当前目录,什么是相对路径名。
    什么是文件路径名?
    Centos6.7安装chrome
    关于Java开发过程中质量提升-2自动化
    关于Java开发过程中质量提升-1代码格式配置
    java质量提升相关
    完成wamp安装后Mysql配置记录
    树莓派raspi2-ubuntu meta安装配置指导
    mysql数据库批量操作
  • 原文地址:https://www.cnblogs.com/mangoyang/p/9314552.html
Copyright © 2011-2022 走看看