P4396 [AHOI2013]作业

P4396 [AHOI2013]作业

比较简单的莫队

思路:莫队搞区间

线段树/树状数组/分块搞权值

第一反应:排序+离散化+线段树+莫队

得到:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<functional>
#include<iostream>
#include<map>
using namespace std;
const int N=100005;
int n,m;
int a[N];
int kans[N],kanss[N];
int be[N];
int len;
int l=1,r=0,ans=0;
struct node{
    int l,r,a,b;
    int rank;
}SSS[N];

inline int read(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
inline bool cmp(node x,node y)
{
    return  be[x.l]^be[y.l]?be[x.l]<be[y.l]:be[x.l]&1?x.r<y.r:x.r>y.r;
}
struct Sugment_Tree{
    int t[N*3];
    int u[N*3];
    void ST(){
        memset(t,0,sizeof(t));
        memset(u,0,sizeof(u));
    }
    #define il inline 
    il void push_up(int num){
        t[num]=(t[num<<1]+t[num<<1|1]); 
        u[num]=(u[num<<1]+u[num<<1|1]);
    }
    il void upt(int l,int r,int num,int POS,int SUM){
        if(l>POS||r<POS) return;
        if(l==r&&r==POS){
            t[num]+=SUM;
            u[num]=(t[num]>0?1:0);
            return;
        }
        int mid=(l+r)>>1;
        upt(l,mid,num<<1,POS,SUM);
        upt(mid+1,r,num<<1|1,POS,SUM);
        push_up(num);
    }
    il int ask(int l,int r,int num,int LL,int RR){
        if(l>RR||r<LL) return 0;
        if(l>=LL&&r<=RR){
            return t[num];
        }
        int mid=(l+r)>>1;
        return ask(l,mid,num<<1,LL,RR)+ask(mid+1,r,num<<1|1,LL,RR);
    }
    il int kakask(int l,int r,int num,int LL,int RR){
        if(l>RR||r<LL) return 0;
        if(l>=LL&&r<=RR){
            return u[num];
        }
        int mid=(l+r)>>1;
        return kakask(l,mid,num<<1,LL,RR)+kakask(mid+1,r,num<<1|1,LL,RR);
    }
}T;
inline void AC(int pos,int val){
    //pos是在原数列里的位置 
    T.upt(1,n,1,a[pos],val);
}
int main(){
    n=read(),m=read();
    len=pow(n,0.444);
    for(register int i=1;i<=n;++i){
        a[i]=read();
    }
    for(register int i=1;i<=n;++i) be[i]=(i/len)+1;
    T.ST();
    for(register int i=1;i<=m;++i){
        SSS[i].l=read();
        SSS[i].r=read();
        SSS[i].a=read();
        SSS[i].b=read();
        SSS[i].rank=i;
    }
    sort(SSS+1,SSS+m+1,cmp);
    for(register int i=1;i<=m;++i){
        while(l<SSS[i].l) AC(l++,-1);
        while(l>SSS[i].l) AC(--l,1);
        while(r<SSS[i].r) AC(++r,1);
        while(r>SSS[i].r) AC(r--,-1);
        
        int LLL,RRR;
        LLL=SSS[i].a;
        RRR=SSS[i].b;
        kans[SSS[i].rank]=T.ask(1,n,1,LLL,RRR),kanss[SSS[i].rank]=T.kakask(1,n,1,LLL,RRR);
    }
    for(register int i=1;i<=m;++i) printf("%d %d\n",kans[i],kanss[i]);
    return 0;
} 
/*
5 5
3 4 1 4 5
*/

关于线段树,它死了......    

表示不会树状数组,又人傻常数大

然后滚粗打分块,哎,打着打着就AC了

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<functional>
#include<iostream>
#include<map>
using namespace std;
const int N=100005;
const int M=505;
int n,m;
int a[N];
int kans[N],kanss[N];
int be[N];
int t[M]={0},tB[M]={0};
int lk[M],rk[M];
int len;
int l=1,r=0;
int happen[N]={0},has[N]={0};
struct node{
    int l,r,a,b;
    int rank;
}SSS[N];

inline int read(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
inline bool cmp(node x,node y)
{
    return  be[x.l]==be[y.l]?x.r<y.r:be[x.l]<be[y.l];
}
struct Sugment_Tree{
    #define il inline 
    il void upt(int x,int v){
        happen[x]+=v;
        t[be[x]]+=v;
        int u=has[x];
        has[x]=happen[x]>0?1:0;
        if(u==1&&has[x]==0) tB[be[x]]--;
        else if(u==0&&has[x]==1) tB[be[x]]++;
    }
    il int ask(int l,int r){
        if(be[l]==be[r]){
            int ans=0;
            for(register int i=l;i<=r;i++){
                ans+=happen[i];
            }
            return ans;
        }
        else{
            int ans=0;
            for(int i=l;i<=rk[be[l]];i++){
                ans+=happen[i];
            }
            for(int i=be[l]+1;i<=be[r]-1;i++) ans+=t[i];
            for(int i=lk[be[r]];i<=r;i++){
                ans+=happen[i];
            }
            return ans;
        }
    }
    il int kakask(int l,int r){
        if(be[l]==be[r]){
            int ans=0;
            for(register int i=l;i<=r;i++){
                ans+=has[i];
            }
            return ans;
        }
        else{
            int ans=0;
            for(int i=l;i<=rk[be[l]];i++){
                ans+=has[i];
            }
            for(int i=be[l]+1;i<=be[r]-1;i++) ans+=tB[i];
            for(int i=lk[be[r]];i<=r;i++){
                ans+=has[i];
            }
            return ans;
        }
    }
}T;
inline void AC(int pos,int val){
    //pos是在原数列里的位置 
    T.upt(a[pos],val);
}
int main(){
    n=read(),m=read();
    len=pow(n,0.5);
    for(register int i=1;i<=n;++i){
        a[i]=read();
    }
    for(register int i=1;i<=n;++i) be[i]=(i/len)+1;
    for(register int i=1;i<=n;++i){
        if(!lk[be[i]]) lk[be[i]]=i;
        rk[be[i]]=i;
    }
    for(register int i=1;i<=m;++i){
        SSS[i].l=read();
        SSS[i].r=read();
        SSS[i].a=read();
        SSS[i].b=read();
        SSS[i].rank=i;
    }
    sort(SSS+1,SSS+m+1,cmp);
    for(register int i=1;i<=m;++i){
        while(l<SSS[i].l) AC(l++,-1);
        while(l>SSS[i].l) AC(--l,1);
        while(r<SSS[i].r) AC(++r,1);
        while(r>SSS[i].r) AC(r--,-1);
        
        int LLL,RRR;
        LLL=SSS[i].a;
        RRR=SSS[i].b;
        kans[SSS[i].rank]=T.ask(LLL,RRR),kanss[SSS[i].rank]=T.kakask(LLL,RRR);
    }
    for(register int i=1;i<=m;++i) printf("%d %d\n",kans[i],kanss[i]);
    return 0;
} 
/*
5 5
3 4 1 4 5
*/

转载于:https://www.cnblogs.com/QYJ060604/p/11488837.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值