zoukankan      html  css  js  c++  java
  • 教主的魔法

    传送门

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

    感觉维护的过程很好想,修改的时候对于整个块都在内的直接打标记,两个零散的区间暴力重构,重新排序。查询的时候,对于整块的,直接在块内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;
    }
  • 相关阅读:
    HDU 3572 Task Schedule(拆点+最大流dinic)
    POJ 1236 Network of Schools(Tarjan缩点)
    HDU 3605 Escape(状压+最大流)
    HDU 1166 敌兵布阵(分块)
    Leetcode 223 Rectangle Area
    Leetcode 219 Contains Duplicate II STL
    Leetcode 36 Valid Sudoku
    Leetcode 88 Merge Sorted Array STL
    Leetcode 160 Intersection of Two Linked Lists 单向链表
    Leetcode 111 Minimum Depth of Binary Tree 二叉树
  • 原文地址:https://www.cnblogs.com/captain1/p/9834471.html
Copyright © 2011-2022 走看看