• 教主的魔法


    传送门

    这道题序列很长,但是操作数很少,然后也没想到什么好的数据结构来维护,那就分块吧。

    感觉维护的过程很好想,修改的时候对于整个块都在内的直接打标记,两个零散的区间暴力重构,重新排序。查询的时候,对于整块的,直接在块内lowerbound一下z-add[i]的位置,零散的话直接暴力计算即可。

    复杂度O(ksqrt(n)logsqrt(n)).注意数组别开小了……

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<set>
    #include<queue>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    
    using namespace std;
    typedef long long ll;
    const int M = 2000005;
    const int N = 2005;
    const ll INF = 1e17+9;
    const ll mod = 19260817;
    
    ll read()
    {
        ll ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
        if(ch == '-') op = -1;
        ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
        ans *= 10;
        ans += ch - '0';
        ans %= mod;
        ch = getchar();
        }
        return ans * op;
    }
    
    ll a[M],b[N][N],l[N],r[N],blo[M],add[N],n,m,B,cnt,g = 1,x,y,z;
    char s[5];
    
    ll query(ll x,ll y,ll z)
    {
        ll L = blo[x],R = blo[y],ans = 0;
        if(L == R)
        {
        rep(i,x,y) if(a[i] + add[L] >= z) ans++;
        return ans;
        }
        rep(i,L+1,R-1)
        {
        //rep(j,1,B) printf("%lld ",b[i][j]);enter;
        //printf("!%lld
    ",z - add[i]);
        int d = lower_bound(b[i]+1,b[i]+B,z - add[i]) - b[i];
        //printf("#%d
    ",d);
        if(d == B && b[i][d] < z - add[i]) continue;
        ans += B - d + 1;
        }
        rep(i,x,r[L]) if(a[i] + add[blo[i]] >= z) ans++;
        rep(i,l[R],y) if(a[i] + add[blo[i]] >= z) ans++;
        return ans;
    }
    
    void modify(ll x,ll y,ll z)
    {
        ll L = blo[x],R = blo[y],cur = 0;
        if(L == R)
        {
        rep(i,x,y) a[i] += z;
        rep(i,l[L],r[L]) b[L][++cur] = a[i];
        sort(b[L]+1,b[L]+1+B);
        return;
        }
        rep(i,L+1,R-1) add[i] += z;
        rep(i,x,r[L]) a[i] += z;
        rep(i,l[R],y) a[i] += z;
        rep(i,l[L],r[L]) b[L][++cur] = a[i];
        sort(b[L]+1,b[L]+B+1),cur = 0;
        rep(i,l[R],r[R]) b[R][++cur] = a[i];
        sort(b[R]+1,b[R]+B+1);
    }
    
    int main()
    {
        n = read(),m = read(),B = sqrt(n);
        cnt = (n % B) ? n / B + 1 : n / B;
        rep(i,1,cnt) l[i] = r[i-1] + 1,r[i] = l[i] + B - 1;
        r[cnt] = n;
        rep(i,1,n) a[i] = read();
        rep(i,1,n)
        {
        blo[i] = g;
        if(i == r[g]) g++;
        }
        rep(i,1,cnt)
        {
        int cur = 0;
        rep(j,l[i],r[i]) b[i][++cur] = a[j];
        sort(b[i]+1,b[i]+B+1);
        }
        rep(i,1,m)
        {
        scanf("%s",s);
        x = read(),y = read(),z = read();
        if(s[0] == 'A') printf("%lld
    ",query(x,y,z));
        else modify(x,y,z);
        }
        return 0;
    }
  • 相关阅读:
    ACE 的一些词汇
    odbc连接不上,初步猜想是myodbc安装有问题
    1分钟 当数据库管理员
    硬件申请
    编译删除
    ASP.NET之数据绑定
    发布、订阅、复制、同步SQL Server 2000 数据库
    SQL——添加约束的语句
    SQL——规则
    十大著名黑客—— 凯文米特尼克
  • 原文地址:https://www.cnblogs.com/captain1/p/9834471.html
Copyright © 2020-2023  润新知