zoukankan      html  css  js  c++  java
  • 洛谷 P5677 [GZOI2017]配对统计(树状数组)

    传送门


    解题思路

    注意有个条件为ai互不相同。

    尝试应用lxl教的套路:
    第一步,将一维问题放到二维平面上:把好的配对(x,y)看做二维平面上的点。于是问题就变成了求出矩形所包含的点的个数。
    第二步,利用数据结构将二维平面问题降到一维解决:离线,把询问按照右端点排序,同时把好的配对按照右端点排序,保证在树状数组里的好的配对的x和y都小于等于当前的r。这样每次查询等于在树状数组里查询(l,r)的和。

    注意事项与细节:

    • 特判n==0的情况
    • 对于点(x,y)要保证x<=y

    AC代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int maxn=3e5+5;
    int n,m,cnt,now;
    long long ans,d[maxn];
    struct node{
    	int l,r,id;
    	long long v;
    }a[maxn],b[maxn],q[maxn];
    bool cmp(node a,node b){
    	return a.r<b.r;
    }
    bool cmp2(node a,node b){
    	return a.v<b.v;
    }
    inline int lowbit(int x){
    	return x&(-x);
    }
    void update(int x,int v){
    	for(int i=x;i<=n;i+=lowbit(i)){
    		d[i]+=v;
    	}
    }
    long long query(int x){
    	long long res=0;
    	for(int i=x;i>=1;i-=lowbit(i)){
    		res+=d[i];
    	}
    	return res;
    }
    int main(){
    	ios::sync_with_stdio(false);
    	cin>>n>>m;
    	if(n==1){
    		cout<<0;
    		return 0;
    	}
    	for(int i=1;i<=n;i++) cin>>a[i].v,a[i].id=i;
    	sort(a+1,a+n+1,cmp2);
    	a[0].v=-1e9;
    	a[n+1].v=2e9;
    	for(int i=1;i<=n;i++){
    		if(a[i].v-a[i-1].v<a[i+1].v-a[i].v){
    			b[++cnt].l=min(a[i-1].id,a[i].id);
    			b[cnt].r=max(a[i-1].id,a[i].id);
    		}else{
    			if(a[i].v-a[i-1].v==a[i+1].v-a[i].v){
    				b[++cnt].l=min(a[i-1].id,a[i].id);
    				b[cnt].r=max(a[i-1].id,a[i].id);
    				b[++cnt].l=min(a[i].id,a[i+1].id);
    				b[cnt].r=max(a[i].id,a[i+1].id);
    			}else{
    				b[++cnt].l=min(a[i].id,a[i+1].id);
    				b[cnt].r=max(a[i].id,a[i+1].id);
    			}
    		}
    	}
    	sort(b+1,b+cnt+1,cmp);
    	for(int i=1;i<=m;i++){
    		cin>>q[i].l>>q[i].r;
    		q[i].id=i;
    	}
    	sort(q+1,q+m+1,cmp);
    	for(int i=1;i<=m;i++){
    		while(now<cnt&&b[now+1].r<=q[i].r){
    			now++;
    			update(b[now].l,1);
    		}
    		ans+=1ll*q[i].id*(query(q[i].r)-query(q[i].l-1));
    		while(i<m&&q[i+1].r==q[i].r){
    			i++;
    			ans+=1ll*q[i].id*(query(q[i].r)-query(q[i].l-1));
    		}
    	}
    	cout<<ans;
    	return 0;
    }
    
  • 相关阅读:
    Pytest学习笔记(二) 用例执行规则
    Pytest学习笔记(一) 环境安装及入门
    Jmeter(十四)取样器之JDBC Request
    Jmeter(十三)阶梯式压测
    Jmeter(十二)常用插件
    Fsync理解
    PostgreSQL checkpoint_completion_target及脏数据刷盘过程说明
    PostgreSQL synchronous_commit参数确认,以及流复制的思考
    性能测试之nmon对linux服务器的监控(转)
    Postgresql的pgcrypto模块(转)
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/15273100.html
Copyright © 2011-2022 走看看