Codeforces Gym 101138 D. Strange Queries
Posted 北屿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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; }
以上是关于Codeforces Gym 101138 D. Strange Queries的主要内容,如果未能解决你的问题,请参考以下文章
D. Black Hills golden jewels 二分答案 + 二分判定
2020-2021 gym/103185 D. Dividing Candy(siweim二进制)