bzoj 3236: [Ahoi2013]作业

来源:互联网 发布:nba赌球软件 编辑:程序博客网 时间:2024/06/05 17:16

易水人去,明月如霜。

思路

很容易看出来是莫队算法,但是对于后面结果的统计,如果直接
暴力的话肯定会超时,所以我们就考虑将其按照权值分块
题目中指出啦其每个位置的值是介于1~N所以我们就可以
分块来提高效率统计ans1的效率,对于ans2
我们可以思考维护一个权值的树状数组就好啦
代码:

#include <cstdio>#include <cstring>#include <iostream>#include <cmath>#include <algorithm>#define N 100005#define M 1000005using namespace std;int n,m,block,x[N],pos[N],ans1[M],ans2[M],num[N];int g1[N];int read(){    char ch;int s=0,f=1;ch=getchar();    while(ch>'9'||ch<'0') { if(ch=='-') f*=-1; ch=getchar(); }    while(ch>='0'&&ch<='9') { s=s*10+ch-48;ch=getchar(); }    return s*f;}struct node { int l,r,a,b,id; bool operator <(const node &t) const {     if(pos[l]==pos[t.l])        return pos[r]<pos[t.r];     return pos[l]<pos[t.l]; }}q[M];struct BIT{ int c[N]; inline int lowbit(int x){ return x&-x; } void add(int pos,int x) {     while(pos<=n)     {         c[pos]+=x;pos+=lowbit(pos);     } } int query(int pos) {     int res=0;     while(pos>0) res+=c[pos],pos-=lowbit(pos);     return res; }}t2;void change(int t,int f){    g1[pos[x[t]]]+=f;    if(num[x[t]]==0&&f==1) t2.add(x[t],1);    else if(num[x[t]]==1&&f==-1) t2.add(x[t],-1);    num[x[t]]+=f;}void query(int id,int a,int b){    if(pos[a]==pos[b])    {        for(int i=a;i<=b;i++)            ans1[id]+=num[i];        return ;    }    for(int i=a;i<=pos[a]*block;i++) ans1[id]+=num[i];    for(int i=pos[a]+1;i<=pos[b]-1;i++) ans1[id]+=g1[i];    for(int i=b;i>(pos[b]-1)*block;i--) ans1[id]+=num[i];}int main(){n=read(),m=read(); block=(int)sqrt(n); for(int i=1;i<=n;i++)    x[i]=read(),pos[i]=(i-1)/block+1; for(int i=1;i<=m;i++)    q[i].l=read(),q[i].r=read(),q[i].a=read(),q[i].b=read(),q[i].id=i; sort(q+1,q+1+m); int l=1,r=0; for(int i=1;i<=m;i++) {        while(l<q[i].l)change(l++,-1);        while(l>q[i].l)change(--l,1);        while(r>q[i].r)change(r--,-1);        while(r<q[i].r)change(++r,1);           query(q[i].id,q[i].a,q[i].b);        ans2[q[i].id]=t2.query(q[i].b)-t2.query(q[i].a-1); }     for(int i=1;i<=m;i++)    printf("%d %d\n",ans1[i],ans2[i]); return 0;}
原创粉丝点击