Description

Input

Output

Sample Input

3 4
1 2 2
1 2 1 3
1 2 1 1
1 3 1 3
2 3 2 3

Sample Output

2 2
1 1
3 2
2 1

HINT

N=100000,M=1000000

 
对权值建立线段树,对应询问在权值区间内打上标记,那么最后对线段树上的每个节点,问题就转化成HH的项链了。
#include<cstdio>
#include<cctype>
#include<queue>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
const int BufferSize=<<;
char buffer[BufferSize],*head,*tail;
inline char Getchar() {
if(head==tail) {
int l=fread(buffer,,BufferSize,stdin);
tail=(head=buffer)+l;
}
return *head++;
}
inline int read() {
int x=,f=;char c=Getchar();
for(;!isdigit(c);c=Getchar()) if(c=='-') f=-;
for(;isdigit(c);c=Getchar()) x=x*+c-'';
return x*f;
}
const int maxn=;
const int maxm=;
const int maxnode=;
int n,m,first[maxn],next[maxn],to[maxn],cnt;
void AddVal(int u,int v) {
next[++cnt]=first[u];to[cnt]=v;first[u]=cnt;
}
int L[maxm],R[maxm],ans[maxm],ans2[maxm],first2[maxn*],next2[maxnode],to2[maxnode],ToT;
void AddQuery(int u,int v) {
next2[++ToT]=first2[u];to2[ToT]=v;first2[u]=ToT;
}
void query(int o,int l,int r,int ql,int qr,int val) {
if(ql<=l&&r<=qr) AddQuery(o,val);
else {
int mid=l+r>>,lc=o<<,rc=lc|;
if(ql<=mid) query(lc,l,mid,ql,qr,val);
if(qr>mid) query(rc,mid+,r,ql,qr,val);
}
}
struct Solver {
int x,v,t;
bool operator < (const Solver& ths) const {
return x<ths.x;
}
}A[maxn],B[maxm];
int sumv[maxn],clo[maxn],nxt[maxn],clo2[maxn],lst[maxn],T,T2;
void add(int x,int v) {
if(x>n) return;
for(;x<=n;x+=x&-x) {
if(clo[x]==T) sumv[x]+=v;
else clo[x]=T,sumv[x]=v;
}
}
int sum(int x) {
int res=;
for(;x;x-=x&-x) if(clo[x]==T) res+=sumv[x];
return res;
}
void solve(int o,int l,int r) {
if(l!=r) {
int mid=l+r>>,lc=o<<,rc=lc|;
solve(lc,l,mid);solve(rc,mid+,r);
}
int m1=,m2=;
rep(x,l,r) ren A[++m1]=(Solver){to[i],x,};
if(!m1||!first2[o]) return;
T++;
rep(i,,m1) add(A[i].x,);
for(int i=first2[o];i;i=next2[i]) ans[to2[i]]+=sum(R[to2[i]])-sum(L[to2[i]]-);
T++;T2++;
for(int i=first2[o];i;i=next2[i]) B[++m2]=(Solver){L[to2[i]],R[to2[i]],to2[i]};
sort(A+,A+m1+);sort(B+,B+m2+);
dwn(i,m1,) {
if(clo2[A[i].v]!=T2) clo2[A[i].v]=T2,lst[A[i].v]=i,nxt[i]=m1+;
else nxt[i]=lst[A[i].v],lst[A[i].v]=i;
}T2++;
rep(i,,m1) if(clo2[A[i].v]!=T2) {
clo2[A[i].v]=T2;
add(A[i].x,);
}
int j=;
rep(i,,m2) {
while(j<=m1&&A[j].x<B[i].x) {
add(A[j].x,-);
if(nxt[j]<=m1) add(A[nxt[j]].x,);
j++;
}
ans2[B[i].t]+=sum(B[i].v)-sum(B[i].x-);
}
}
int main() {
n=read();m=read();
rep(i,,n) AddVal(read(),i);
rep(i,,m) {
L[i]=read();R[i]=read();
int a=read(),b=read();
query(,,n,a,b,i);
}
solve(,,n);
rep(i,,m) printf("%d %d\n",ans[i],ans2[i]);
return ;
}

莫队大法也很资瓷啊。对权值分块以牺牲询问复杂度的代价来降低修改复杂度。

不知道为什么O(Msqrt(N))的做法比O(Mlog^2N)的做法快了3倍。。。

#include<cstdio>
#include<cctype>
#include<queue>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
const int BufferSize=<<;
char buffer[BufferSize],*head,*tail;
inline char Getchar() {
if(head==tail) {
int l=fread(buffer,,BufferSize,stdin);
tail=(head=buffer)+l;
}
return *head++;
}
inline int read() {
int x=,f=;char c=Getchar();
for(;!isdigit(c);c=Getchar()) if(c=='-') f=-;
for(;isdigit(c);c=Getchar()) x=x*+c-'';
return x*f;
}
const int maxn=;
const int maxm=;
int n,m,A[maxn],blo[maxn],st[maxn],en[maxn];
struct Query {
int l,r,a,b,id;
bool operator < (const Query& ths) const {
if(blo[l]==blo[ths.l]) return r<ths.r;
return l<ths.l;
}
}Q[maxm];
int ans[maxm],ans2[maxm],cnt[maxn],sum[maxn],bloans[maxn];
void add(int x) {
if(!cnt[x]) bloans[blo[x]]++;
cnt[x]++;sum[blo[x]]++;
}
void del(int x) {
cnt[x]--;sum[blo[x]]--;
if(!cnt[x]) bloans[blo[x]]--;
}
void query(int x,int l,int r) {
rep(i,blo[l]+,blo[r]-) ans2[x]+=bloans[i],ans[x]+=sum[i];
if(blo[l]==blo[r]) rep(i,l,r) ans2[x]+=(cnt[i]>),ans[x]+=cnt[i];
else {
rep(i,l,en[blo[l]]) ans2[x]+=(cnt[i]>),ans[x]+=cnt[i];
rep(i,st[blo[r]],r) ans2[x]+=(cnt[i]>),ans[x]+=cnt[i];
}
}
int main() {
n=read();m=read();int SIZE=(int)sqrt(n);
rep(i,,n) {
A[i]=read();blo[i]=(i-)/SIZE+;
if(!st[blo[i]]) st[blo[i]]=i;
en[blo[i]]=i;
}
rep(i,,m) Q[i].l=read(),Q[i].r=read(),Q[i].a=read(),Q[i].b=read(),Q[i].id=i;
sort(Q+,Q+m+);
int l=,r=;
rep(i,,m) {
while(l>Q[i].l) add(A[--l]);
while(r<Q[i].r) add(A[++r]);
while(l<Q[i].l) del(A[l++]);
while(r>Q[i].r) del(A[r--]);
query(Q[i].id,Q[i].a,Q[i].b);
}
rep(i,,m) printf("%d %d\n",ans[i],ans2[i]);
return ;
}

BZOJ3236: [Ahoi2013]作业的更多相关文章

  1. [bzoj3809]Gty的二逼妹子序列/[bzoj3236][Ahoi2013]作业

    [bzoj3809]Gty的二逼妹子序列/[bzoj3236][Ahoi2013]作业 bzoj   bzoj 题目大意:一个序列,m个询问在$[l,r]$区间的$[x,y]$范围内的数的个数/种类. ...

  2. BZOJ3236 [Ahoi2013]作业 【莫队 + 树状数组】

    题目链接 BZOJ3236 题解 没想到这题真的是如此暴力 #include<algorithm> #include<iostream> #include<cstring ...

  3. [BZOJ3236]:[Ahoi2013]作业(莫队+分块)

    题目传送门 题目描述 此时已是凌晨两点,刚刚做了$Codeforces$的小$A$掏出了英语试卷.英语作业其实不算多,一个小时刚好可以做完.然后是一个小时可与做完的数学作业,接下来是分别都是一个小时可 ...

  4. BZOJ3236[Ahoi2013]作业——莫队+树状数组/莫队+分块

    题目描述 输入 输出 样例输入 3 4 1 2 2 1 2 1 3 1 2 1 1 1 3 1 3 2 3 2 3 样例输出 2 2 1 1 3 2 2 1 提示 N=100000,M=1000000 ...

  5. BZOJ3236:[AHOI2013]作业(莫队,分块)

    Description Input Output Sample Input 3 4 1 2 2 1 2 1 3 1 2 1 1 1 3 1 3 2 3 2 3 Sample Output 2 2 1 ...

  6. BZOJ3236: [Ahoi2013]作业 树状数组维护 莫队

    水果~~~~ 关于四个while可行性的证明:区间有正确性所以不管那团小东西用没有duang~反它最终总会由于两次覆盖二准确 关于区间种数可行性的证明:他会在0 1间(或两边)来回跳动(过程中),最终 ...

  7. 【莫队算法】【权值分块】bzoj3236 [Ahoi2013]作业

    莫队显然.然后维护转移的时候如果用树状数组,则很容易TLE.所以用权值分块维护转移. 总复杂度O(m*sqrt(n)). #include<cstdio> #include<algo ...

  8. [BZOJ3236][AHOI2013]作业:树套树/莫队+分块

    分析 第一问随便搞,直接说第二问. 令原数列为\(seq\),\(pre_i\)为\(seq_i\)这个值上一个出现的位置,于是可以简化询问条件为: \(l \leq i \leq r\) \(a \ ...

  9. bzoj3809 Gty的二逼妹子序列 & bzoj3236 [Ahoi2013]作业 莫队+分块

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3809 https://lydsy.com/JudgeOnline/problem.php?id ...

随机推荐

  1. 做网站用UTF-8还是GB2312 & 各国语言对应字符集

    经常我们打开外国网站的时候出现乱码,又或者打开很多非英语的外国网站的时候,显示的都是口口口口口的字符, WordPress程序是用的UTF-8,很多cms用的是GB2312. ● 为什么有这么多编码? ...

  2. JavaScript String 对象方法

    String 对象方法 方法 描述 anchor() 创建 HTML 锚. big() 用大号字体显示字符串. blink() 显示闪动字符串. bold() 使用粗体显示字符串. charAt() ...

  3. ios如何生成crash报告

    #include <signal.h> #include <execinfo.h> void OnProcessExceptionHandler(int sigl) { do ...

  4. msysgit ls 中文显示

    2013年10月17日 14:54:15 安装了新版的msysgit后,在其自带的 git bash 命令行下就可以输入中文汉字了 但是创建了中文名字命名的文件后,再用 ls 命令查询时会出现乱码的情 ...

  5. 用数据表创建树_delphi教程

    数据库结构:字段 类型ID 整型 索引(无重复)name 文本father 整型 //tree初始化procedure TForm1.FormActivate(Sender: TObject);var ...

  6. Java for LeetCode 152 Maximum Product Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  7. hadoop中常见的问题

    一.在root下进行格式化 这样很糟糕 这样的话,若是第一次装的话,我的建议是将生成的文件都删掉,恢复到最开始的状态, 1. 首先你需要删除 vi conf/hdfs-site.xml   配置文件的 ...

  8. Man简单介绍

    转自:http://os.51cto.com/art/201312/425525.htm Linux系统提供了相对比较丰富的帮助手册(man),man是manual的缩写,在日常linux系统管理中经 ...

  9. 推荐:移动端前端UI库—Frozen UI、WeUI、SUI Mobile

    Frozen UI 自述:简单易用,轻量快捷,为移动端服务的前端框架. 主页:http://frozenui.github.io/ 开发团队:QQVIP FD Team Github:https:// ...

  10. Java Hour 40 Maven ( 2 )

    有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. Hour 40 Maven 坐标 任何一个包都需要一个全世界唯一的id, Ma ...