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. BZOJ 1600

    开始刷一些USACO月赛题了.. 这题简单递推就不说了. 然后我们发现暴力递推是$O(n^2)$的.看起来非常慢. 这道题拥有浓厚的数学色彩,因此我们可以从数学它的规律上找突破口. (于是暴力大法好, ...

  2. 一步步实现Nagios监控linux主机及飞信报警

    一步步实现Nagios监控linux主机及飞信报警 上篇文章介绍了在linux主机上架设nagios监控服务,并对windows主机进行服务状态变化的监控,这次我们继续上次内容.      首先实现n ...

  3. ubuntu创建文件夹快捷方式命令

    sudo ln -sT /path/to/source/directory  /path/to/destination/directory 注意路径一定要用 绝对路径 例: /site-package ...

  4. POJ 2418

    http://poj.org/problem?id=2418 这是一个二叉树的题目,但我看了下书,还是不是特别理解会用二叉树,所以我就用其他的办法来做,结果一样AC,时间也就1700多ms,比起二叉树 ...

  5. windows下如何对mysql进行整裤备份

    通常情况下备份一个数据库,直接单裤备份即可,更完善一点的会要求做到定时单裤备份.然而很多时候又由于裤实例是在太多,这样会导致备份非常耗时,因而有时候需要对整个数据库应用进行备份.那么在windows下 ...

  6. DP:炮兵阵地问题(POJ 1185)

    正确的打炮方式(大雾)(点我查看) 2015-08-21 问题是中文的,大家可以进去看看. 先说一个坑,这个问题我交了很多次,都没过,反正是WA到我烦了,都不知道哪里错了!!!怎么会有错,然后翻了一下 ...

  7. [Java基础] System.arraycopy使用

    转载自:http://blog.csdn.net/java2000_net/article/details/4059465 System提供了一个native 静态方法arraycopy(),我们可以 ...

  8. dbVisualizer连接mysql

  9. shell定时任务

    1.认识Croncron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业.由于Cron 是Linux的内置服务,但它不自动起来,可以用以下的方法启动.关闭这个服务:/sbin/se ...

  10. undefined reference to 'typeinfo for android::Thread'

    原因:工程使用了系统库libstagefright.so,而该库是Android系统用no-rtti方式编译出来的,因此我们的工程也必须要用no-rtti方式编译. 解决方法:在Application ...