分析
我们发现可以通过容斥得到Ans = sum(1,R1,1,R2) - sum(1,R1,1,L2-1) - sum(1,L1-1,1,R2) + sum(1,L1-1,L2-1)
于是我们可以吧一个询问分成4部分
然后进行莫队即可
代码
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cctype> #include<cmath> #include<cstdlib> #include<ctime> #include<queue> #include<vector> #include<set> #include<map> #include<stack> using namespace std; #define int long long int belong[400100],block,n,m,num1[400100],num2[400100],ans[400100],Ans,a[400100],cnt; struct node { int le,ri,id,wh; }; node d[400100]; inline bool cmp(const node a,const node b){ if(belong[a.le]==belong[b.le])return a.ri<b.ri; return a.le<b.le; } signed main(){ int i,j,k,L=1,R=0; scanf("%lld",&n); block=sqrt(n); for(i=1;i<=n;i++)belong[i]=(i-1)/block+1; for(i=1;i<=n;i++)scanf("%lld",&a[i]); scanf("%lld",&m); for(i=1;i<=m;i++){ int x1,x2,y1,y2; scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2); d[++cnt]=(node){y1,y2,i,1}; d[++cnt]=(node){x1-1,y2,i,-1}; d[++cnt]=(node){y1,x2-1,i,-1}; d[++cnt]=(node){x1-1,x2-1,i,1}; } sort(d+1,d+cnt+1,cmp); for(i=1;i<=cnt;i++){ while(L>d[i].le){ Ans-=num2[a[L]]; num1[a[L]]--; L--; } while(L<d[i].le){ L++; Ans+=num2[a[L]]; num1[a[L]]++; } while(R<d[i].ri){ R++; Ans+=num1[a[R]]; num2[a[R]]++; } while(R>d[i].ri){ Ans-=num1[a[R]]; num2[a[R]]--; R--; } ans[d[i].id]+=d[i].wh*Ans; } for(i=1;i<=m;i++)printf("%lld\n",ans[i]); return 0; }
原文地址:https://www.cnblogs.com/yzxverygood/p/10527367.html
时间: 2024-11-17 01:02:41