• [BZOJ3236]作业


    作业

    题目描述

    image

    输入格式

    image

    输出格式

    image

    样例

    样例输入

    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

    真难受,打了两节半晚课,一开始连点思路都没有,颓题解发现全世界的题解都是"莫队+分块/树状数组"就结束了,一气之下颓了代码,我不是人,看了半天才研究明白代码(?),这也不是个多难的题啊,我更不是人了,结果发现颓的代码是个WA0的?一脸懵逼,我今天招惹谁了?mmp,我发现我最近每天晚上都要吐槽一大堆,最近运势不太对,讲题吧,明天该考试了,期待rp++

    我怕我写个莫队+树状数组然后贴个代码会rp--,所以说一说吧,顺便复习一下树状数组(我发现我都忘光了),后面的pa大哥现在在说这是道水题,我???又是一脸懵逼,不扯了

    其实这道题说是莫队其实挺明显的,查询区间还不用修改,莫队很优秀啊,不过关于那个大于等于a,小于等于b,其实我没想到怎么处理,后来颓完代码,觉得,树状数组真是个优秀的办法,单点修改,区间查询,莫队+树状数组优秀啊,我们来想想树状数组要维护些什么,偷偷告诉你,要两个树状数组哦显然,问题既然是两个,那就维护那两个问题呗,一个维护区间中出现过多少个不同的数,一个维护区间中一共多少个数,这样的话,我们用莫队进行++--的操作,然后对于每个询问中的[a,b]进行区间查询,优秀的不的了,然后树状数组一波搞,然后就可以A了,不过关于出现了多少个不同的数值可不能随随便便搞,他只能是当你区间中只有一个这个数,你把它搞掉了,或者没有这个数,你搞进来了一个,才可以修改这个答案,一共有多少个数,每次移动区间都修改就对了,emm,大概真的就是个莫队的模板+树状数组的模板,还是我太弱了,不过这题分块也可以,有兴趣的自己试一试,说不定线段树也没毛病呢

     1 //数值的个数就是只算一遍
     2 //数的个数就是重复的也算
     3 #include<cmath>
     4 #include<cstdio>
     5 #include<iostream>
     6 #include<algorithm>
     7 #define maxn 100010
     8 #define maxm 1000100
     9 using namespace std;
    10 struct node{
    11     int l,r,a,b,bh,sz,s;
    12 }q[maxm];
    13 int n,m,kc;
    14 int a[maxn],ss[maxn],SZ[maxm],S[maxm],cs[maxm];
    15 int lowbit(int x)
    16 {
    17     return x&(-x);
    18 }
    19 bool cmp(const node &a,const node &b)
    20 {
    21     return ss[a.l]==ss[b.l]?a.r<b.r:a.l<b.l;
    22 }
    23 bool cmpp(const node &a,const node &b)
    24 {
    25     return a.bh<b.bh;
    26 }
    27 void add(int x,int c)
    28 {
    29     for(int i=x;i<=n;i+=lowbit(i))  S[i]+=c;
    30 }
    31 void addd(int x,int c)
    32 {
    33     for(int i=x;i<=n;i+=lowbit(i))  SZ[i]+=c;
    34 }
    35 int sum(int x)
    36 {
    37     int c=0;
    38     for(int i=x;i;i-=lowbit(i))  c+=S[i];
    39     return c;
    40 }
    41 int summ(int x)
    42 {
    43     int c=0;
    44     for(int i=x;i;i-=lowbit(i))  c+=SZ[i];
    45     return c;
    46 }
    47 void upd(int x,int c)
    48 {
    49     if(c==1&&++cs[a[x]]==1)  addd(a[x],c);
    50     if(c==-1&&--cs[a[x]]==0)  addd(a[x],c);
    51     add(a[x],c);
    52 }
    53 int main()
    54 {
    55     scanf("%d%d",&n,&m);  kc=sqrt(n);
    56     for(int i=1;i<=n;++i)  {scanf("%d",&a[i]);  ss[i]=i/kc+1;}
    57     for(int i=1;i<=m;++i)
    58     {
    59         scanf("%d%d%d%d",&q[i].l,&q[i].r,&q[i].a,&q[i].b);
    60         q[i].bh=i;
    61     }
    62     sort(q+1,q+m+1,cmp);
    63     int z=1,y=0;
    64     for(int i=1;i<=m;++i)
    65     {
    66         while(z<q[i].l)  upd(z++,-1);
    67         while(z>q[i].l)  upd(--z,1);
    68         while(y<q[i].r)  upd(++y,1);
    69         while(y>q[i].r)  upd(y--,-1);
    70         q[i].s=sum(q[i].b)-sum(q[i].a-1);
    71         q[i].sz=summ(q[i].b)-summ(q[i].a-1);
    72     }
    73     sort(q+1,q+m+1,cmpp);
    74     for(int i=1;i<=m;++i)  printf("%d %d
    ",q[i].s,q[i].sz);
    75     return 0;
    76 }
    跑了27s的代码
  • 相关阅读:
    可搜索的下拉框
    Vue 父组件调用子组件的方法
    vue中异步函数async和await的用法
    用配置文件的方法发送axios请求
    vue中 localStorage的使用方法(详解)
    下拉框 组件的使用
    遇到不懂的记录
    做测试平台可能会用到的东西
    下拉框 v-for循环拿值的方法
    ant 自定义遮罩
  • 原文地址:https://www.cnblogs.com/hzjuruo/p/11240890.html
Copyright © 2020-2023  润新知