Codeforces Round #442 (Div. 2) F. Ann and Books(莫队)

来源:互联网 发布:fastdfs nginx 400 编辑:程序博客网 时间:2024/06/09 18:29

题目链接:http://codeforces.com/problemset/problem/877/F


貌似每次查询区间内所有的子区间的问题一般都用莫队啊?


然后发现其实有用的值只有3*n个,所以可以全部离散化之后做到nsqrt(n)。


要特殊处理以L为头的区间的。剩下的题解说的挺清楚的了。


代码:

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int MAXN=1e5+5;ll sum[MAXN],Ans[MAXN],ans;ll HASH[MAXN*3],LEFT[MAXN],RIGHT[MAXN],sv[MAXN*3];int pos[MAXN],t[MAXN],a[MAXN],tot;struct query{    int l,r,id;}Q[MAXN];bool cmp(const query a,const query b){    if(pos[a.l]==pos[b.l])        return a.r<b.r;    return pos[a.l]<pos[b.l];}int getid(ll x){int ret=lower_bound(HASH+1,HASH+1+tot,x)-HASH;return ret;}int L=1,R=0;void DelLeft(){sv[sum[L]]--;ans-=sv[RIGHT[L]];L++;}void DelRight(){sv[sum[R]]--;ans-=sv[LEFT[R]];R--;}void AddLeft(){L--;ans+=sv[RIGHT[L]];sv[sum[L]]++;}void AddRight(){R++;ans+=sv[LEFT[R]];sv[sum[R]]++;}int main(){//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);int n,k,q;scanf("%d%d",&n,&k);int sz=ceil(sqrt(1.0*n));tot=0;for(int i=1;i<=n;i++){scanf("%d",&t[i]);}for(int i=1;i<=n;i++){scanf("%d",&a[i]);}for(int i=1;i<=n;i++){sum[i]=sum[i-1]+((t[i]==1?1:-1)*a[i]);pos[i]=(i-1)/sz;LEFT[i]=sum[i]-k;RIGHT[i]=sum[i]+k;HASH[++tot]=sum[i];HASH[++tot]=LEFT[i];HASH[++tot]=RIGHT[i];}HASH[++tot]=0;HASH[++tot]=k;HASH[++tot]=-k;sum[0]=0;LEFT[0]=-k;RIGHT[0]=k;sort(HASH+1,HASH+1+tot);tot=unique(HASH+1,HASH+1+tot)-HASH-1;for(int i=0;i<=n;i++){sum[i]=getid(sum[i]);LEFT[i]=getid(LEFT[i]);RIGHT[i]=getid(RIGHT[i]);}scanf("%d",&q);for(int i=1;i<=q;i++){scanf("%d%d",&Q[i].l,&Q[i].r);Q[i].id=i;}sort(Q+1,Q+1+q,cmp);ans=0;for(int i=1;i<=q;i++)    {        int id=Q[i].id;        while(R<Q[i].r)AddRight();        while(L>Q[i].l)AddLeft();        while(R>Q[i].r)DelRight();        while(L<Q[i].l)DelLeft();        Ans[id]=ans+sv[RIGHT[L-1]];    }for(int i=1;i<=q;i++){printf("%lld\n",Ans[i]);}return 0;}


阅读全文
0 0
原创粉丝点击