zoukankan      html  css  js  c++  java
  • 分块小集

    UVA12003 Array Transformer  

    给一列数,每次询问  将 a[ pi ]  的值 更新为  li  到  ri  区间中小于  vi 的个数 *  u / (r-l+1);

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    const int M = 3e5 + 10, SIZE = 4096;
    int B[M/SIZE + 1][SIZE + 1], a[M], n;
    int read(){
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*=f;    
    }
    int solve(int L, int R, int v){
        int ret = 0;
        int bl = (L-1)/SIZE, br = (R-1)/SIZE;
        if(bl == br){
            for(int i = L; i <= R; i++) ret += a[i] < v;
            return ret;
        }
        for(int i = L; i <= (bl+1) * SIZE; i++) ret += a[i] < v;
        for(int i = br*SIZE+1; i <= R; i++) ret += a[i] < v;
        for(int i = bl + 1; i < br; i++) ret += lower_bound(B[i] + 1, B[i] + 1 + SIZE, v) - B[i] - 1;
        return ret;
    }
    void add(int pos, int x){
        if(a[pos] == x)return ;
        int w = (pos-1)/SIZE;
        int tt = 1;
        while(B[w][tt] != a[pos])tt++;
        a[pos] = x;
        B[w][tt] = x;
        while(tt < SIZE && B[w][tt] > B[w][tt+1]) swap(B[w][tt], B[w][tt+1]), tt++;
        while(tt > 1 && B[w][tt] < B[w][tt-1]) 
        swap(B[w][tt], B[w][tt-1]), tt--;
    }
    int main(){
        //freopen("c.in","r",stdin);
        //freopen("my.out","w",stdout);
        int n, m, u;
        scanf("%d%d%d", &n, &m, &u);
        int blo = 0, j = 0;
        for(int i = 1; i <= n; i++){
            a[i] = read();
            B[blo][++j] = a[i];
            if(j == SIZE){j = 0, blo++;}
        }
        for(int i = 0; i < blo; i++)
            sort(B[i]+1, B[i]+1+SIZE);
        if(j) sort(B[blo]+1, B[blo]+1+j);
        while(m--){
            
            int L = read(), R = read(), v = read(), p = read();
            int k = solve(L, R, v);
            add(p, 1LL*u*k/(R-L+1));
            //for(int i = 1; i <= n; i++)printf("%d ", a[i]);puts("");
        }
        for(int i = 1; i <= n; i++) printf("%d
    ", a[i]);
    }

    P4168 [Violet]蒲公英

    求区间众数;

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    using namespace std;
    
    const int M = 50005;
    int cnt[M], a[M], len, n, m, b[M], f[205][205], c[205][M], place[M];
    
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    
    void init(int x){
        memset(cnt, 0, sizeof(cnt));
        int ans = 0;
        for(int i = x * len + 1; i <= n; i++){
            int bl = place[i];
            cnt[a[i]]++;
            if(cnt[a[i]] > cnt[ans] || (cnt[a[i]] == cnt[ans] && a[i] < ans)) ans = a[i];
            f[x][bl] = ans;
        }
    }
    
    int query(int lf, int rg){
        int ans = 0, mx = 0;
        if(place[rg]) ans = f[place[lf]+1][place[rg]-1];
        if(place[rg]) mx = c[place[rg]-1][ans] - c[place[lf]][ans];
        bool fg = place[lf]+1 <= place[rg]-1;
        for(int i = lf; i <= min((place[lf]+1)*len, rg); i++){
            int tt = ++cnt[a[i]]; 
            if(fg) tt += (c[place[rg]-1][a[i]] - c[place[lf]][a[i]]);
            if(tt > mx || (tt == mx && a[i] < ans)) mx = tt, ans = a[i];
        }
        if(place[lf] != place[rg])
            for(int i = place[rg]*len + 1; i <= rg; i++){
                int tt = ++cnt[a[i]];
                if(fg) tt += (c[place[rg]-1][a[i]] - c[place[lf]][a[i]]);
                if(tt > mx || (tt == mx && a[i] < ans)) mx = tt, ans = a[i];
            }
        
        for(int i = lf; i <= min((place[lf]+1)*len, rg); i++)cnt[a[i]] = 0;
        if(place[lf] != place[rg])
            for(int i = place[rg]*len + 1; i <= rg; i++)cnt[a[i]] = 0;        
        return ans;
    }
    
    
    int main(){
        //freopen("c.in","r",stdin);
        //freopen("my.out","w",stdout);
        scanf("%d%d", &n, &m);
        len = sqrt(n + 0.5);
        for(int i = 1; i <= n; i++)a[i] = b[i] = read();
        sort(b + 1, b + 1 + n);
        int tot = unique(b + 1, b + 1 + n) - b - 1;
        for(int i = 1; i <= n; i++){
            a[i] = lower_bound(b + 1, b + 1 + tot, a[i]) - b;
            place[i] = (i - 1)/len;
            c[place[i]][a[i]] = ++cnt[a[i]];
        }
        for(int i = 0; i <= place[n]; i++)init(i);
        for(int i = 1; i <= tot; i++)
            for(int j = 1; j <= place[n]; j++)
                if(!c[j][i]) c[j][i] = c[j - 1][i];
        //for(int i=0;i<=place[n];i++)for(int j=0;j<=place[n];j++)printf("%d ", f[i][j]);
        int lst = 0, l, r;
        memset(cnt, 0, sizeof(cnt));
        while(m--){
            l = read(), r = read();
            l = (l + lst - 1) % n + 1, r = (r + lst - 1) % n + 1;
            if(l > r)swap(l, r);
            lst = b[query(l, r)];
            printf("%d
    ",lst);
            //printf("%d %d %d
    ", l, r, lst);
        }
    } 
  • 相关阅读:
    java 反编译和文档生成器
    java 导入自定义类
    hust 1010 最短循环节点
    KMP算法
    hiho 第119周 最大权闭合子图
    2007 Asia
    hiho 第1周 最长回文子串
    hiho 第118周 网络流四·最小路径覆盖
    hiho 第117周 二分图多重匹配,网络流解决
    成为一名JAVA高级工程师你需要学什么
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/9878313.html
Copyright © 2011-2022 走看看