zoukankan      html  css  js  c++  java
  • Luogu5268 SNOI2017一个简单的询问

    Description

    link

    给定一个长度为 (n) 的序列,定义函数 (get(l,r,x))(x) 在区间 ([ l,r ]) 的出现次数

    (m) 个询问,每个询问给出四个参数 (l_1,r_1,l_2,r_2),求出

    [sum_{x=0}^{infty} get(l_1,r_1,x) imes get(l_2,r_2,x) ]

    Solution

    首先我们发现 (get(l,r,x)) 这样的函数并不是很好求,而且是乘积

    那么我们差分一下:(get(1,r,x)-get(1,l-1,x))

    把式子一展开,我们的每个询问就变成了四个类似的从 (1) 开始,求区间相关值乘积了

    (把 (get(1,y,x)) 直接写成 (get(y,x)) 了)

    [sum_{x=0} ^{infty} get(l_1-1,x) imes get(l_2-1,x)+get(r_1-1,x) imes get(r_2-1,x)-get(l_1-1,x) imes get(r_2,x)-get(r_1,x) imes get(l_2-1,x) ]

    直接莫队 (+) 贡献统计即可

    其实不太像入门题意义下的莫队,就是在统计答案的时候排序优化复杂度的一个方法

    Code

    #include<bits/stdc++.h>
    using namespace std;
    namespace yspm{
    	inline int read()
    	{
    		int res=0,f=1; char k;
    		while(!isdigit(k=getchar())) if(k=='-') f=-1;
    		while(isdigit(k)) res=res*10+k-'0',k=getchar();
    		return res*f;
    	}
    	const int N=50010;
    	int n,T,cnt,a[N],bl[N],block,l,r;
    	struct node{
    		int l,r,fl,id;
    		inline void init(int a,int b,int c,int d){l=a,r=b,fl=c,id=d; return ;}
    		bool operator <(const node s) const
    		{
    			if(bl[l]!=bl[s.l]) return bl[l]<bl[s.l];
    			return r<s.r;
    		}
    	}q[N<<2];
    	int app1[N],app2[N],res,ans[N];
    	inline void del1(int x)
    	{
    		app1[x]--; res-=app2[x];
    		return ;
    	}
    	inline void add1(int x)
    	{
    		app1[x]++; res+=app2[x];
    		return ;
    	}
    	inline void add2(int x)
    	{
    		app2[x]++; res+=app1[x];
    		return ;
    	}
    	inline void del2(int x)
    	{
    		app2[x]--; res-=app1[x];
    		return ;
    	}
    	signed main()
    	{
    		n=read(); block=sqrt(n);
    		for(int i=1;i<=n;++i) bl[i]=(i-1)/block+1,a[i]=read();
    		T=read();
    		for(int i=1,l1,l2,r1,r2;i<=T;++i)
    		{
    			l1=read(),r1=read(),l2=read(),r2=read();
    			q[++cnt].init(l1-1,l2-1,1,i);
    			q[++cnt].init(r1,r2,1,i);
    			q[++cnt].init(l1-1,r2,-1,i);
    			q[++cnt].init(r1,l2-1,-1,i);
    		}
    		for(int i=1;i<=cnt;++i)
    		{
    			if(q[i].l>q[i].r) swap(q[i].l,q[i].r);
    		} sort(q+1,q+cnt+1);
    		for(int i=1;i<=cnt;++i)
    		{
    			while(l<q[i].l) ++l,add1(a[l]);
    			while(l>q[i].l) del1(a[l]),--l;
    			while(r<q[i].r) ++r,add2(a[r]);
    			while(r>q[i].r) del2(a[r]),--r;
    			ans[q[i].id]+=q[i].fl*res;
    		}
    		for(int i=1;i<=T;++i) printf("%d
    ",ans[i]);
    		return 0;
    	}
    }
    signed main(){return yspm::main();}
    
  • 相关阅读:
    LeetCode 1245. Tree Diameter
    LeetCode 1152. Analyze User Website Visit Pattern
    LeetCode 1223. Dice Roll Simulation
    LeetCode 912. Sort an Array
    LeetCode 993. Cousins in Binary Tree
    LeetCode 1047. Remove All Adjacent Duplicates In String
    LeetCode 390. Elimination Game
    LeetCode 1209. Remove All Adjacent Duplicates in String II
    LeetCode 797. All Paths From Source to Target
    LeetCode 1029. Two City Scheduling
  • 原文地址:https://www.cnblogs.com/yspm/p/13235122.html
Copyright © 2011-2022 走看看