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

    P5268 [SNOI2017]一个简单的询问

    莫队+差分。

    首先这里是两个区间,显然不好直接做,于是可以考虑差分,我们维护前缀区间,把柿子改写成四个答案组合起来。

    这样改写出来的四个小答案都可以使用莫队来求,然后拼起来就行了。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    template <typename T>
    inline void read(T &x){
    	x=0;char ch=getchar();bool f=false;
    	while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
    	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    	x=f?-x:x;
    	return ;
    }
    template <typename T>
    inline void write(T x){
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar(x%10^48);
    	return ;
    }
    #define ll long long 
    const int N=5e5+5;
    int n,m,a[N];
    int bl[N],cnt[N],d[N],siz;
    ll Ans[N],now,Num[N],tl[N],tr[N];
    struct Query{
    	int l,r,id,tag;
    	inline bool operator<(const Query&d)const{return bl[l]!=bl[d.l]?l<d.l:(bl[l]&1?r<d.r:r>d.r);}
    }Q[N];
    int main(){
    	read(n);
    	for(int i=1;i<=n;i++) read(a[i]);
    	read(m);int top=0;
    	for(int i=1;i<=m;i++){
    		int l1,r1,l2,r2;
    		read(l1),read(r1),read(l2),read(r2);
    		Q[++top]=Query{r1,r2,i,1};
    		Q[++top]=Query{l2-1,r1,i,-1};
    		Q[++top]=Query{l1-1,r2,i,-1};
    		Q[++top]=Query{l1-1,l2-1,i,1};
    	}
    	const int t=sqrt(top);
    	for(int i=1;i<=n;i++) bl[i]=(i-1)/t+1;
    	sort(Q+1,Q+top+1);
    	int l=0,r=0;
    	for(int i=1;i<=top;i++){
    		if(Q[i].l<1||Q[i].r<1)continue;
    		while(l<Q[i].l) now+=tr[a[++l]],++tl[a[l]];
    		while(l>Q[i].l) now-=tr[a[l]],--tl[a[l--]];
    		while(r<Q[i].r) now+=tl[a[++r]],++tr[a[r]];
    		while(r>Q[i].r) now-=tl[a[r]],--tr[a[r--]];
    		Ans[Q[i].id]+=now*Q[i].tag;
    	}
    	for(int i=1;i<=m;i++) write(Ans[i]),putchar('
    ');
    	return 0;
    }
    
  • 相关阅读:
    奈良有鹿
    Luogu P1892 团伙
    Luogu P1330 封锁阳光大学
    java读取property文件
    collection
    testNG学习
    maven项目学习
    Android.mk详解二
    sdk开发经验
    工作经验
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14686624.html
Copyright © 2011-2022 走看看