• LOJ#2254. 「SNOI2017」一个简单的询问 莫队


    求 $,sum_{x=0}^{infty} get(l,r,x)get(l_{2},r_{2},x),q$ 组询问.

    由于这里的 $get$ 会涉及到两个区间,所以十分不好处理.

    那么我们就要想办法把这个式子转化成只和一个区间有关的东西.

    考虑拆成前缀和,即 $(s[r]-s[l-1]) imes (s[r_{2}]-s[l_{2}-1])$

    $Rightarrow s[r]s[r_{2}]-s[r]s[l_2-1]-s[l-1]s[r_2]+s[l-1]s[l_2-1]$

    然后我们把这 4 个值看成是新的 4 个区间,用莫队解一下就行了.    

    code: 

    #include <bits/stdc++.h>     
    #define N 50009   
    #define ll long long 
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;   
    int a[N],n,B,m;    
    ll tot,sum[2][N],Ans[N];                 
    struct que
    {   
    	int l,r,id,op;   
    	que(int l=0,int r=0,int id=0,int op=0):l(l),r(r),id(id),op(op){}   
    	bool operator<(const que b) const 
    	{   
    		return (l/B)==(b.l/B)?r<b.r:(l/B)<(b.l/B);     
    	}   
    }q[N<<2];      
    void add(int x,int o) 
    {                     
    	tot-=sum[o][x]*sum[o^1][x];      
    	++sum[o][x];   
    	tot+=sum[o][x]*sum[o^1][x];  
    } 
    void del(int x,int o) 
    {    
    	tot-=sum[o][x]*sum[o^1][x];   
    	--sum[o][x];   
    	tot+=sum[o][x]*sum[o^1][x];   
    }
    int main() 
    { 
    	// setIO("input");       
    	int l=1,r=1,cnt=0,x,y,z;  
    	scanf("%d",&n),B=sqrt(n);         
    	for(int i=1;i<=n;++i) scanf("%d",&a[i]);        
    	scanf("%d",&m);   
    	for(int i=1;i<=m;++i) 
    	{
    		int l1,r1,l2,r2;  
    		scanf("%d%d%d%d",&l1,&r1,&l2,&r2);   
    		q[++cnt]=que(min(r1,r2),max(r1,r2),i,1);  
    		if(l2>1) q[++cnt]=que(min(l2-1,r1),max(l2-1,r1),i,-1);   
    		if(l1>1) q[++cnt]=que(min(l1-1,r2),max(l1-1,r2),i,-1);   
    		if(l1>1&&l2>1) q[++cnt]=que(min(l1-1,l2-1),max(l1-1,l2-1),i,1);   
    	}
    	sort(q+1,q+1+cnt);   
    	sum[0][a[1]]=sum[1][a[1]]=1,tot=1;             
    	for(int i=1;i<=cnt;++i) 
    	{      
    		while(r<q[i].r) add(a[++r],0);   
    		while(l<q[i].l) add(a[++l],1);   
    		while(l>q[i].l) del(a[l--],1);   
    		while(r>q[i].r) del(a[r--],0);              
    		Ans[q[i].id]+=q[i].op*tot;   
    	}        
    	for(int i=1;i<=m;++i)  printf("%lld
    ",Ans[i]);  
    	return 0; 
    }
    

      

  • 相关阅读:
    VC 常见问题百问
    python windows 环境变量
    Check server headers and verify HTTP Status Codes
    Where are the AES 256bit cipher suites? Please someone help
    outlook 如何预订会议和会议室
    安装Axis2的eclipse插件后,未出现界面
    windows 环境变量
    python 时间日期处理汇集
    openldap学习笔记(使用openldap2.3.32)
    set p4 environment in windows
  • 原文地址:https://www.cnblogs.com/guangheli/p/13073688.html
Copyright © 2020-2023  润新知