zoukankan      html  css  js  c++  java
  • BZOJ 3744 Gty的妹子序列 分块+树状数组

    具体分析见 搬来大佬博客
    时间复杂度 O(nnlogn)O(nsqrt nlogn)

    CODE

    #include <cmath>
    #include <cctype>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    
    char cb[1<<15],*cs=cb,*ct=cb;
    #define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
    template<class T>inline void read(T &res) {
        char ch; int flg = 1; for(;!isdigit(ch=getc());)if(ch=='-')flg=-flg;
        for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0'); res*=flg;
    }
    const int MAXN = 50005;
    const int SQRT = 230;
    int n, q, a[MAXN], B, bel[MAXN], tail[SQRT], blocks, b[MAXN], tot;
    int T[MAXN], f[SQRT][MAXN], g[SQRT][MAXN];
    
    inline void upd(int x, int val) {
    	while(x) T[x] += val, x -= x&-x;
    }
    
    inline int qsum(int x) {
    	int res = 0;
    	while(x <= tot) res += T[x], x += x&-x;
    	return res;
    }
    
    inline void solvef(int i, int s) {
    	for(int j = s; j <= n; ++j)
    		f[i][j] = f[i][j-1] + qsum(a[j]+1), upd(a[j], 1);
    	for(int j = s; j <= n; ++j) upd(a[j], -1);
    }
    
    inline void solveg(int i, int t) {
    	for(int j = t; j; --j)
    		g[i][j] = g[i][j+1] + qsum(1)-qsum(a[j]), upd(a[j], 1);
    	for(int j = t; j; --j) upd(a[j], -1);
    }
    
    inline int head(int i) { return (i-1)*B + 1; }
    
    int main () {
    	read(n); B = sqrt(n);
    	blocks = (n-1)/B + 1;
    	for(int i = 1; i <= n; ++i)
    		read(a[i]), bel[i] = (i-1)/B + 1, tail[bel[i]] = i, b[++tot] = a[i];
    	sort(b + 1, b + tot + 1);
    	tot = unique(b + 1, b + tot + 1) - b - 1;
    	for(int i = 1; i <= n; ++i)
    		a[i] = lower_bound(b + 1, b + tot + 1, a[i]) - b;
    	for(int i = 1; i <= SQRT; ++i)
    		solvef(i, head(i)), solveg(i, tail[i]);
    	read(q);
    	int lastans = 0, l, r;
    	while(q--) {
    		read(l), read(r);
    		l ^= lastans, r ^= lastans;
    		lastans = f[bel[l]][r] + g[bel[r]][l] - f[bel[l]][tail[bel[r]]];
    		for(int i = head(bel[l]); i < l; ++i) upd(a[i], 1);
    		for(int i = r+1; i <= tail[bel[r]]; ++i) lastans += qsum(a[i]+1);
    		for(int i = head(bel[l]); i < l; ++i) upd(a[i], -1);
    		printf("%d
    ", lastans);
    	}
    }
    
  • 相关阅读:
    php+redis简易消息队列
    Linux关闭selinux的方法(临时关闭和永久关闭)
    Linux清理buff/cache
    Centos禁止ping的设置方法
    浅谈mysql触发器
    mysql中left join right join inner join用法分析
    mysql主从配置详解(图文)
    mysql中的几种判断语句
    mysql锁表处理方法
    Mysql里的order by与索引
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039356.html
Copyright © 2011-2022 走看看