zoukankan      html  css  js  c++  java
  • [BJOI2016]回转寿司

    似乎没有人打平衡树的题解,那我就来水一发~

    我们将题目做一个简单的转化:

    (sum_i = sum_{j=1}^{i} a_j)

    那么答案就是(sum_{i=1}^{n}sum_{j=1}^{i} (L leq (sum_i - sum_{j-1}) leq R))

    我们可以利用容斥的思想进行简单是转化:

    (sum_{i=1}^{n}sum_{j=1}^{i} (L leq (sum_i - sum_{j-1})) - sum_{i=1}^{n}sum_{j=1}^{i} (R < (sum_i - sum_{j-1})))

    因此,我们只用枚举(sum_i),并在一个可以接受的时间复杂度内分别找到相对应的(j)的数目,即(sum_{j - 1} leq sum_i - L)(j)的个数和(sum_{j - 1} leq sum_i - R - 1)(j)的数量,并把他们相减。

    而查找这些数目完全可以用平衡树来实现,下面的代码打的是(treap),仅供参考。

    注:题目的数据范围似乎有问题,似乎是(0 leq L , Rleq 10^9)

    #include <cstdio>
    #include <ctime>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    const int MAXN = 1e5 + 5;
    
    struct node {
    	LL lc , rc , data , pri , si , cnt;
    }t[MAXN];
    
    void Zig(LL &k) {
    	LL y = t[k].lc;
    	t[k].lc = t[y].rc;
    	t[y].rc = k;
    	t[y].si = t[k].si;
    	t[k].si = t[t[k].lc].si + t[t[k].rc].si + t[k].cnt;
    	k = y;
    }
    
    void Zag(LL &k) {
    	LL y = t[k].rc;
    	t[k].rc = t[y].lc;
    	t[y].lc = k;
    	t[y].si = t[k].si;
    	t[k].si = t[t[k].lc].si + t[t[k].rc].si + t[k].cnt;
    	k = y;
    }
    
    LL num = 0;
    void Insert(LL &k , LL key) {
    	if(!k) {
    		k = ++num;
    		t[k].data = key;t[k].pri = rand();
    		t[k].si = 1;t[k].cnt = 1;
    		return;
    	} 
    	t[k].si ++;
    	if(t[k].data == key) t[k].cnt ++;
    	else if(t[k].data < key) {
    		Insert(t[k].rc , key);
    		if(t[t[k].rc].pri < t[k].pri) Zag(k);
    	}
    	else {
    		Insert(t[k].lc , key);
    		if(t[t[k].lc].pri < t[k].pri) Zig(k);
    	}
    }
    
    LL n , rt;
    
    LL x_rank(LL x) {
    	LL k = rt , ans = 0;
    	while(k) {
    		if(x == t[k].data) return ans + t[t[k].lc].si + t[k].cnt;
    		if(x > t[k].data) ans += t[t[k].lc].si + t[k].cnt , k = t[k].rc;
    		else k = t[k].lc;
    	}
    	return ans;
    }
    
    LL L , R , a[MAXN];
    int main() {
    	srand(19491001);
    	scanf("%lld %lld %lld" , &n , &L , &R);
    	for (int i = 1; i <= n; ++i) {
    		scanf("%lld" , &a[i]);
    		a[i] += a[i - 1];
    	}
    	LL ans = 0;
    	Insert(rt , 0);
    	for (int i = 1; i <= n; ++i) {
    		ans += x_rank(a[i] - L);
    		ans -= x_rank(a[i] - R - 1); 
    		Insert(rt , a[i]);
    	}
    	printf("%lld" , ans);
    	return 0;
    }
    
  • 相关阅读:
    Delphi WebService连接数据库
    编写一个单独的Web Service for Delphi7(步骤)
    Delphi stdCall意义
    Delphi WEB APP DEBUGGER是如何使用的
    用delphi的THTTPRIO控件调用了c#写的webservice。
    Delphi 编写的Web Service
    Delphi WebService 中 Web App Debugger 的建议
    flex布局浅谈和实例
    IOS开关效果
    文字渐变和边框渐变
  • 原文地址:https://www.cnblogs.com/Reanap/p/13423233.html
Copyright © 2011-2022 走看看