[Snoi2017]一个简单的询问

数据范围很容易让人想到莫队算法

但是对于每次询问有\(l_1,r_1,l_2,r_2\)四个参数

很不方便维护

所以可以将询问差分

\(get(l,r,x)=get(1,r,x)-get(1,l-1,x)\)

\(get(l_1,r_1,x)*get(l_2,r_2,x)\)

\(=get(1,r_1,x)*get(1,r_2,x)\)

\(-get(1,l_1-1,x)*get(1,r_2,x)\)

\(-get(1,r_1,x)*get(1,l_2-1,x)\)

\(+get(1,l_1-1,x)*get(1,l_2-1,x)\)

于是原问题转化为四个只有两个参数的问题且可以使用莫队求解的问题

#include<bits/stdc++.h>

using namespace std;

#define gc c=getchar()
#define r(x) read(x)
#define ll long long

template<typename T>
inline void read(T&x){
    x=0;T k=1;char gc;
    while(!isdigit(c)){if(c==‘-‘)k=-1;gc;}
    while(isdigit(c)){x=x*10+c-‘0‘;gc;}x*=k;
}

const int N=50005;

int be[N],a[N];

struct Query{
    int l,r,type,id;
    bool operator < (Query x) const{
        return be[l]==be[x.l]?r<x.r:l<x.l;
    }
};

ll Ans[N];
vector<Query> Q;

int cntl[N],cntr[N];

int main(){
    int n,m;r(n);
    int block_size=sqrt(n);
    for(int i=1;i<=n;++i){
        r(a[i]);
        be[i]=(i-1)/block_size+1;
    }
    r(m);
    for(int i=1,l1,r1,l2,r2;i<=m;++i){
        r(l1),r(r1),r(l2),r(r2);
        Q.push_back(Query{r1,r2,1,i});
        if(l1>1)Q.push_back(Query{l1-1,r2,-1,i});
        if(l2>1)Q.push_back(Query{r1,l2-1,-1,i});
        if(l1>1&&l2>1)Q.push_back(Query{l1-1,l2-1,1,i});
    }
    sort(Q.begin(),Q.end());
    ll ans=0;
    int l=0,r=0;
    for(int i=0;i<Q.size();++i){
        Query &x=Q[i];

        while(l<x.l)cntl[a[++l]]++,ans+=cntr[a[l]];
        while(l>x.l)cntl[a[l]]--,ans-=cntr[a[l--]];
        while(r<x.r)cntr[a[++r]]++,ans+=cntl[a[r]];
        while(r>x.r)cntr[a[r]]--,ans-=cntl[a[r--]];

        Ans[x.id]+=x.type*ans;
    }
    for(int i=1;i<=m;++i)printf("%lld\n",Ans[i]);
}

原文地址:https://www.cnblogs.com/yicongli/p/9819208.html

时间: 2024-08-07 01:55:43

[Snoi2017]一个简单的询问的相关文章

【BZOJ5016】[Snoi2017]一个简单的询问 莫队

[BZOJ5016][Snoi2017]一个简单的询问 Description 给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出 get(l,r,x)表示计算区间[l,r]中,数字x出现了多少次. Input 第一行,一个数字N,表示序列长度. 第二行,N个数字,表示a1-aN 第三行,一个数字Q,表示询问个数. 第4-Q+3行,每行四个数字l1,r1,l2,r2,表示询问. N,Q≤50000 N1≤ai≤N 1≤l1≤r1≤N 1≤l2≤r2≤N

bzoj 5016: [Snoi2017]一个简单的询问

Description 给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出 get(l,r,x)表示计算区间[l,r]中,数字x出现了多少次. Input 第一行,一个数字N,表示序列长度.第二行,N个数字,表示a1-aN第三行,一个数字Q,表示询问个数.第4-Q+3行,每行四个数字l1,r1,l2,r2,表示询问.N,Q≤50000N1≤ai≤N1≤l1≤r1≤N1≤l2≤r2≤N注意:答案有可能超过int的最大值Output 对于每组询问,输出一行一

【bzoj5016】[Snoi2017]一个简单的询问 莫队算法

题目描述 给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出 get(l,r,x)表示计算区间[l,r]中,数字x出现了多少次. 输入 第一行,一个数字N,表示序列长度. 第二行,N个数字,表示a1-aN 第三行,一个数字Q,表示询问个数. 第4-Q+3行,每行四个数字l1,r1,l2,r2,表示询问. N,Q≤50000 N1≤ai≤N 1≤l1≤r1≤N 1≤l2≤r2≤N 注意:答案有可能超过int的最大值 输出 对于每组询问,输出一行一个数字,表

bzoj5016 [Snoi2017]一个简单的询问

传送门 分析 我们发现可以通过容斥得到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

【LOJ2254】SNOI2017一个简单的询问

莫队,每次询问的是两个区间,就把区间拆开,分开来算就好了. 借鉴了rank1大佬的玄学排询问的姿势. #include<bits/stdc++.h> #define N 50010 typedef long long ll; using namespace std; inline int read(){ int f=1,x=0;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); do{x=x*10+ch-

[BZOJ5016]一个简单的询问

给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出 get(l,r,x)表示计算区间[l,r]中,数字x出现了多少次. Input 第一行,一个数字N,表示序列长度. 第二行,N个数字,表示a1-aN 第三行,一个数字Q,表示询问个数. 第4-Q+3行,每行四个数字l1,r1,l2,r2,表示询问. N,Q≤50000 N1≤ai≤N 1≤l1≤r1≤N 1≤l2≤r2≤N 注意:答案有可能超过int的最大值 Output 对于每组询问,输出一行一个数字

bzoj 5016 一个简单的询问

THUWC 考了莫队(这个应该可以说吧) 然而不会莫队,签到失败,所以找到了一道长得差不多的题写一写 为什么这么长时间都没有发现这道题(半恼 给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出 get(l,r,x)表示计算区间[l,r]中,数字x出现了多少次. sol: 把一个询问拆成 4 个前缀询问,注意到 $\sum\limits_{x=0}^{\infty}get(l_1,r_1,x) \cdot get(l_2,r_2,x) = \sum\lim

Win32编程API 基础篇 -- 2.一个简单的窗口 根据英文教程翻译

一个简单的窗口 例子:简单的窗口 有时人们在IRC提问,”我应该怎样制作一个窗口”...嗯,这恐怕不是完全这么简单好回答!其实这并不难一旦你明白你在做什么,但在你得到一个可展示的窗口之前还有一些事情需要我们去做,我们只需要简单地聊聊快速做下笔记,这个问题就能被很简单的回答. 我很喜欢先动手再学习...一下就是一个简单的窗口的程序,我们将会简短的对它进行解释说明. 1 #include <windows.h> 2 3 const char g_szClassName[] = "myWi

5、使用Libgdx设计一个简单的游戏------雨滴

(原文:http://www.libgdx.cn/topic/49/5-%E4%BD%BF%E7%94%A8libgdx%E8%AE%BE%E8%AE%A1%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E6%B8%B8%E6%88%8F-%E9%9B%A8%E6%BB%B4) 在深入研究Libgdx提供的API之前,我们先来创建一个简单的游戏来感受一下libgdx各个功能.这里将简单的对一些功能做介绍. 使用的技术: 文件访问 清除屏幕 渲染图片 使