[bzoj3236][Ahoi2013]作业(莫队+树状数组)

【题目链接】http://www.lydsy.com/JudgeOnline/problem.php?id=3236
【呆马】

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<iostream>
const int N=1e5+1,M=1e6+1;
using namespace std;
struct st{int n,l,r,x,y;} q[M];
int n,m,l,r,i,a[N],p[N],num[N],ans1[M],ans2[M],tree1[N],tree2[N];
int read()
{
    int x=0;char ch;
    for (ch=getchar();ch<'0' || ch>'9';ch=getchar());
    for (;ch>='0' && ch<='9';ch=getchar()) x=x*10+ch-'0';
    return x;
}
bool cmp(st a,st b){return p[a.l]==p[b.l]?a.r<b.r:p[a.l]<p[b.l];}
void modify(int *tree,int x,int y){for (;x<=n;x+=x&-x) tree[x]+=y;}
int sum(int *tree,int x){int t=0; for (;x;x-=x&-x) t+=tree[x]; return t;}
void add(int x)
{
    modify(tree1,x,1);
    num[x]++;
    if (num[x]==1) modify(tree2,x,1);
}
void dele(int x)
{
    modify(tree1,x,-1);
    num[x]--;
    if (!num[x]) modify(tree2,x,-1);
}
int main()
{
        n=read(),m=read();
        l=sqrt(n);
        for (i=1;i<=n;i++)
        {
            p[i]=(i-1)/l;
            a[i]=read();
        }
        for (i=1;i<=m;i++)
        {
            q[i].n=i;
            q[i].l=read(),q[i].r=read(),q[i].x=read(),q[i].y=read();
        }
        sort(q+1,q+m+1,cmp);
        l=r=q[1].l;
        r--;
        for (i=1;i<=m;i++)
        {
            for (;l<q[i].l;dele(a[l++]));
            for (;r>q[i].r;dele(a[r--]));
            for (;l>q[i].l;add(a[--l]));
            for (;r<q[i].r;add(a[++r]));
            ans1[q[i].n]=sum(tree1,q[i].y)-sum(tree1,q[i].x-1);
            ans2[q[i].n]=sum(tree2,q[i].y)-sum(tree2,q[i].x-1);
        }
        for (i=1;i<=m;i++) printf("%d %d\n",ans1[i],ans2[i]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值