zoukankan      html  css  js  c++  java
  • HDU 6315 Naive Operations

    http://acm.hdu.edu.cn/showproblem.php?pid=6315

    题目

    In a galaxy far, far away, there are two integer sequence $a$ and $b$ of length $n$.

    $b$ is a static permutation of $1$ to $n$. Initially a is filled with zeroes.

    There are two kind of operations:

    1. add l r: add one for $a_l,a_{l+1}dots a_r$

    2. query l r: query $sum_{i=l}^rlfloor ai/bi floor$

    Input

    There are multiple test cases, please read till the end of input file.

    For each test case, in the first line, two integers n,q, representing the length of a,b and the number of queries.

    In the second line, n integers separated by spaces, representing permutation b.

    In the following q lines, each line is either in the form 'add l r' or 'query l r', representing an operation.

    $1 leqslant n,q leqslant 100000, 1 leqslant l leqslant rleqslant n$, there're no more than 5 test cases.

    Output

    Output the answer for each 'query', each one line.

    题解

    其实根本不会做……

    $lfloor a/b floor = frac{a-a\%b}{b}$,记录$a$和$a\%b$比较麻烦,因此记录$frac{a-a\%b}{b}=oldsymbol{v}$和$a\%b=oldsymbol{b}$(我就喜欢乱用符号= =)

    那么只需某处$oldsymbol{b}=0$就将v单点修改+1,容易用线段树写出来……(注意可能同时有多个地方=0)

    因为$n,q leqslant 100000$,b又是一个1~n的排列,所以所有和小于$sum_{i=1}^nfrac{n}{i}=n(ln{n}+gamma+frac{1}{2n})approx nln{n}<10^8$,所以可以用int存

    但是为了确定某处的$oldsymbol{b}$,直接暴力$q imes2n>10^9$肯定超时,因此需要技巧……

    因为并不是所有的$oldsymbol{b}$每时每刻都为0,所以还需要点技巧,将$oldsymbol{b}$设为$b-a\%b$,所以只需要关心最小的那个$oldsymbol{b}$,同样可以用线段树维护(+区间),每次维护$log{n}$

    加起来$mathcal{O}(nlog{n})$

    查询的时候并不需要向下和向上更新

    还要注意更新延迟变量$ ext{d}oldsymbol{b}$时不要写成等号= =

    AC代码

    #include<cstdio>
    #include<cstdlib>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #define REP(r,x,y) for(register int r=(x); r<(y); r++)
    #define REPE(r,x,y) for(register int r=(x); r<=(y); r++)
    #define PERE(r,x,y) for(register int r=(x); r>=(y); r--)
    #ifdef sahdsg
    #define DBG(...) printf(__VA_ARGS__),fflush(stdout)
    #else
    #define DBG(...) (void)0
    #endif
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    
    char ch; int si;
    char buf[1<<21],*p1=buf,*p2=buf;
    int beof = 0;
    #define gc() (beof?EOF:(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?(beof=EOF):*p1++))
    
    template<class T>
    inline void read(T &x) {
        x=0; si=1; for(ch=gc();!isdigit(ch) && ch!='-';ch=gc()) if(beof) return;
        if(ch=='-'){si=-1,ch=gc();} for(;isdigit(ch);ch=gc())x=x*10+ch-'0';
        x*=si;
    }
    //template<class T, class...A> inline void read(T &x, A&...a){read(x); read(a...);}
    
    #define MAXN 100007
    int b[MAXN];
    
    struct node {
        int v,b,db;
        int l,r;
    } st[MAXN*4];
    
    inline void st0(int p, int l, int r) {
        st[p].l=l, st[p].r=r, st[p].v=st[p].db=0;
        if(l==r) {
            st[p].b=b[l];
            return;
        }
        int m=(l+r)>>1;
        st0(p*2,l,m);
        st0(p*2+1,m+1,r);
        st[p].b=min(st[p*2].b,st[p*2+1].b);
    }
    
    inline void spreadb(int p) {
        if(st[p].db) {
            st[p*2].db+=st[p].db; st[p*2].b-=st[p].db;
            st[p*2+1].db+=st[p].db; st[p*2+1].b-=st[p].db;
            st[p].db=0;
        }
    }
    
    inline void op_C(int p) {
        if(st[p].l==st[p].r) {
            st[p].v++; st[p].b=b[st[p].l];
            return;
        }
        spreadb(p);
        if(!st[p*2].b) op_C(p*2);
        if(!st[p*2+1].b) op_C(p*2+1);
        st[p].v=st[p*2].v+st[p*2+1].v;
        st[p].b=min(st[p*2].b, st[p*2+1].b);
    }
    
    inline void opA(int p, int l, int r) {
        if(l<=st[p].l && r>=st[p].r) {
            st[p].b--; st[p].db++;
            if(st[p].b==0) {
                op_C(p);
            }
            return;
        }
        spreadb(p);
        int m=(st[p].l+st[p].r)>>1;
        if(l<=m) opA(p*2,l,r);
        if(r>m) opA(p*2+1,l,r);
        st[p].v=st[p*2].v+st[p*2+1].v;
        st[p].b=min(st[p*2].b, st[p*2+1].b);
    }
    
    inline int opQ(int p, int l, int r) {
        if(l<=st[p].l && r>=st[p].r) {
            return st[p].v;
        }
        int m=(st[p].l+st[p].r)>>1;
        int ans=0;
        if(l<=m) ans+=opQ(p*2,l,r);
        if(r>m) ans+=opQ(p*2+1,l,r);
        return ans;
    }
    
    int main() {
    #ifdef sahdsg
        freopen("in.txt","r",stdin);
    #endif
        int n,q;
        read(n);read(q);
        while(!beof) {
            REPE(i,1,n) read(b[i]);
            st0(1,1,n);
            while(0<q--) {
                char k; do k=gc(); while(isspace(k));
                int l,r; read(l); read(r);
                if(k=='a') opA(1,l,r);
                else printf("%d
    ", opQ(1,l,r));
            }
            read(n); read(q);
    
        }
        return 0;
    }
    
  • 相关阅读:
    使用replaceAll替换“/”为“/”
    如何在Lucene里面进行数字范围搜索 (Numeric Range Query)
    Java中的参数传递
    安装配置WordPress 3.0的多站点功能
    Apache Hadoop 项目介绍
    Java中的Set操作
    使用Desktop API in Java SE 6打开文件或者网页
    Java集合(转帖)
    数据结构牛客网习题纠错130
    PAT 1045 Favorite Color Stripe[dp][难]
  • 原文地址:https://www.cnblogs.com/sahdsg/p/10828831.html
Copyright © 2011-2022 走看看