zoukankan      html  css  js  c++  java
  • Codeforces Gym 101138 D. Strange Queries

    Description

    给你一下长度为 (n) 的序列.

    (a_i=a_j)

    (l_1 leqslant i leqslant r_1)

    (l_2 leqslant i leqslant r_2)

    询问满足条件的 ((i,j)) 对数.

    Sol

    分块+前缀和.

    非常乱搞啊...

    首先分块 (O(sqrt{n})) 一块.

    然后在每块里统计块中元素出现次数.

    先预处理块与块之间的贡献,然后处理不足一块的.

    处理块与块之间的时候,需要前缀和优化一下就可以了,枚举当前块中的元素,复杂度 (O(n sqrt{n})).

    处理不足一块的时候有好多细节...自己随便yy一下吧..

    总复杂度 (O(n sqrt{n})) .

    Code

    #include<cstdio>
    #include<cmath>
    #include<iostream>
    using namespace std;
    
    typedef long long LL;
    const int N = 50005;
    const int M = 250;
    #define debug(a) cout<<#a<<" = "<<a<<" "
    
    int n,m,tmp,q,B;
    struct Block{ int a[N],b[M],c; }b[M];
    int bl[N],a[N],t1[N],t2[N],t3[N],t4[N];
    LL f[M][M];
    
    inline int in(int x=0,char ch=getchar()){ while(ch>'9' || ch<'0') ch=getchar();
    	while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
    int GetBl(int x){ if(bl[x] == bl[x-1]) return bl[x]+1;else return bl[x]; }
    int GetBr(int x){ if(bl[x] == bl[x+1]) return bl[x]-1;else return bl[x]; }
    LL work(int l1,int r1,int l2,int r2){
    	int L1=GetBl(l1),R1=GetBr(r1),L2=GetBl(l2),R2=GetBr(r2);LL res=0;
    	
    //	debug(l1),debug(r1),debug(l2),debug(r2)<<endl;
    //	debug(L1),debug(R1),debug(L2),debug(R2)<<endl;
    	
    	//Block and Block
    	if(L2<=R2) for(int i=L1;i<=R1;i++) res+=f[i][R2]-f[i][L2-1];
    	
    //	debug(res)<<endl;
    	
    	//count
    	int c1=0,c2=0;
    	if(bl[l1] != bl[r1]){
    //		cout<<"qwq"<<endl;
    		for(int i=l1;bl[i]<L1;i++) t1[++c1]=a[i],t2[a[i]]++;
    		for(int i=B*R1+1;i<=r1;i++) t1[++c1]=a[i],t2[a[i]]++;
    	}else{
    		if(bl[l1-1]==bl[l1] || bl[r1]==bl[r1+1]) for(int i=l1;i<=r1;i++) t1[++c1]=a[i],t2[a[i]]++;
    	}
    	
    //	cout<<"----------"<<endl;
    //	for(int i=1;i<=c1;i++) cout<<t1[i]<<" ";cout<<endl;
    		
    	if(bl[l2]!=bl[r2]){
    		for(int i=l2;bl[i]<L2;i++) t3[++c2]=a[i],t4[a[i]]++;
    		for(int i=B*R2+1;i<=r2;i++) t3[++c2]=a[i],t4[a[i]]++;
    	}else{
    		if(bl[l2-1]==bl[l2] || bl[r2]==bl[r2+1]) for(int i=l2;i<=r2;i++) t3[++c2]=a[i],t4[a[i]]++;
    	}
    	
    //	for(int i=1;i<=c2;i++) cout<<t3[i]<<" ";cout<<endl;
    //	cout<<"----------"<<endl;
    	
    	// leave l1r1 and [l2,r2]
    	for(int i=1;i<=c1;i++) res+=(L2<=R2 ? b[R2].a[t1[i]]-b[L2-1].a[t1[i]] : 0) + t4[t1[i]];
    	// leave l2r2 and [L1,R1]
    	if(L1<=R1) for(int i=1;i<=c2;i++) res+=b[R1].a[t3[i]]-b[L1-1].a[t3[i]];
    	
    	//clear
    	for(int i=1;i<=c1;i++) t2[t1[i]]--;
    	for(int i=1;i<=c2;i++) t4[t3[i]]--;
    	
    	return res;
    }
    int main(){
    //	freopen("in.in","r",stdin);
    	ios::sync_with_stdio(false);
    	n=in(),m=1,B=sqrt(n)+1;
    	for(int i=1;i<=n;i++){
    		if(b[m].c >= B) ++m;
    		a[i]=in(),bl[i]=m,b[m].b[++b[m].c]=a[i];
    //		debug(a[i]),debug(b[m].c)<<endl;
    	}
    	
    //	debug(m)<<endl;
    //	for(int i=1;i<=m;i++) cout<<b[i].c<<endl;
    	
    	for(int i=1;i<=m;i++){
    		for(int j=1;j<=n;j++) b[i].a[j]=b[i-1].a[j];
    //		for(int i=1;i<=n;i++) cout<<bl[i]<<" ";cout<<endl;
    		for(int j=1;j<=b[i].c;j++) b[i].a[b[i].b[j]]++;
    //		for(int i=1;i<=n;i++) cout<<bl[i]<<" ";cout<<endl;
    	}
    	
    //	for(int i=1;i<=n;i++) cout<<bl[i]<<" ";cout<<endl;
    	
    	for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) for(int k=1;k<=b[i].c;k++) f[i][j]+=b[j].a[b[i].b[k]];
    	
    //	for(int i=1;i<=n;i++) cout<<bl[i]<<" ";cout<<endl;
    	
    	for(q=in();q--;){
    		int l1=in(),r1=in(),l2=in(),r2=in();
    		cout<<work(l1,r1,l2,r2)<<endl;
    	}return 0;
    }
    

      

  • 相关阅读:
    (转)Entity Framework 4.1 之三(由4.0过渡到4.1/4.3)
    (转)修改的T4代码生成器(续)
    (转)【Smart Code Generator】 基于T4的代码生成器
    linux下播放mp3
    poj 2777 Count Color
    poj 1062 昂贵的聘礼
    uva 991 Safe Salutations
    uva 10587 Mayor's posters
    poj 2528 Mayor's posters
    逆序数
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6005716.html
Copyright © 2011-2022 走看看