• 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;
    }
    
  • 相关阅读:
    ==和equals
    instanceof和相关函数
    格式化输出
    [转]使用String的intern方法节省内存
    [转]请别再拿“String s = new String("xyz");创建了多少个String实例”来面试了吧
    Go编程语言学习笔记
    [javascript]什么是闭包?
    [javascript]彻底理解 JS 中 this 的指向
    constrained属性
    Python python 数据类型的相互转换
  • 原文地址:https://www.cnblogs.com/sahdsg/p/10828831.html
Copyright © 2020-2023  润新知