• P1527 [国家集训队]矩阵乘法 [整体二分]


    权值排序,整体二分,没了。

    // by Isaunoya
    #include <bits/stdc++.h>
    using namespace std;
    
    #define rep(i, x, y) for (register int i = (x); i <= (y); ++i)
    #define Rep(i, x, y) for (register int i = (x); i >= (y); --i)
    #define int long long
    
    const int _ = 1 << 21;
    struct I {
    	char fin[_], *p1 = fin, *p2 = fin;
    	inline char gc() {
    		return (p1 == p2) && (p2 = (p1 = fin) + fread(fin, 1, _, stdin), p1 == p2) ? EOF : *p1++;
    	}
    	inline I& operator>>(int& x) {
    		bool sign = 1;
    		char c = 0;
    		while (c < 48) ((c = gc()) == 45) && (sign = 0);
    		x = (c & 15);
    		while ((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15);
    		x = sign ? x : -x;
    		return *this;
    	}
    	inline I& operator>>(double& x) {
    		bool sign = 1;
    		char c = 0;
    		while (c < 48) ((c = gc()) == 45) && (sign = 0);
    		x = (c - 48);
    		while ((c = gc()) > 47) x = x * 10 + (c - 48);
    		if (c == '.') {
    			double d = 1.0;
    			while ((c = gc()) > 47) d = d * 0.1, x = x + (d * (c - 48));
    		}
    		x = sign ? x : -x;
    		return *this;
    	}
    	inline I& operator>>(char& x) {
    		do
    			x = gc();
    		while (isspace(x));
    		return *this;
    	}
    	inline I& operator>>(string& s) {
    		s = "";
    		char c = gc();
    		while (isspace(c)) c = gc();
    		while (!isspace(c) && c != EOF) s += c, c = gc();
    		return *this;
    	}
    } in;
    struct O {
    	char st[100], fout[_];
    	signed stk = 0, top = 0;
    	inline void flush() {
    		fwrite(fout, 1, top, stdout), fflush(stdout), top = 0;
    	}
    	inline O& operator<<(int x) {
    		if (top > (1 << 20)) flush();
    		if (x < 0) fout[top++] = 45, x = -x;
    		do
    			st[++stk] = x % 10 ^ 48, x /= 10;
    		while (x);
    		while (stk) fout[top++] = st[stk--];
    		return *this;
    	}
    	inline O& operator<<(char x) {
    		fout[top++] = x;
    		return *this;
    	}
    	inline O& operator<<(string s) {
    		if (top > (1 << 20)) flush();
    		for (char x : s) fout[top++] = x;
    		return *this;
    	}
    } out;
    #define pb emplace_back
    #define fir first
    #define sec second
    
    template < class T > inline void cmax(T & x , const T & y) {
    	(x < y) && (x = y) ;
    }
    template < class T > inline void cmin(T & x , const T & y) {
    	(x > y) && (x = y) ;
    }
    
    int n , m ;
    const int N = 500 + 10 ; 
    const int M = 6e4 + 10 ;
    struct point { int x , y , val ; } a[N * N] ;
    struct que { int x , y , x2 , y2 , k , id ; } q[M] ;
    int mcnt = 0 ;
    int c[N][N] ;
    int low(int x) { return x & -x ; }
    void add(int x , int y , int v) {
    	for(int i = x ; i <= n ; i += low(i)) for(int j = y ; j <= n ; j += low(j)) c[i][j] += v ;
    }
    int qry(int x , int y) {
    	if(! x || ! y) return 0 ;
    	int ans = 0 ;
    	for(int i = x ; i > 0 ; i ^= low(i)) for(int j = y ; j > 0 ; j ^= low(j)) ans += c[i][j] ;
    	return ans ;
    }
    int qry(int x , int y , int x2 , int y2) {
    	return qry(x2 , y2) - qry(x - 1 , y2) - qry(x2 , y - 1) + qry(x - 1 , y - 1) ;	
    }
    int ans[M] ;
    que t1[M] , t2[M] ;
    void solve(int l , int r , int ql , int qr) {
    	if(ql > qr) return ;
    	if(l == r) {
    		rep(i , ql , qr) ans[q[i].id] = a[l].val ;
    		return ;
    	}
    	int mid = l + r >> 1 ;
    	rep(i , l , mid) add(a[i].x , a[i].y , 1) ;
    	int cnt1 = 0 , cnt2 = 0 ;
    	rep(i , ql , qr) {
    		int res = qry(q[i].x , q[i].y , q[i].x2 , q[i].y2) ;
    		if(res >= q[i].k) t1[++ cnt1] = q[i] ;
    		else { t2[++ cnt2] = q[i] ; t2[cnt2].k -= res ; }
    	}
    	rep(i , l , mid) add(a[i].x , a[i].y , -1) ;
    	rep(i , 1 , cnt1) q[i + ql - 1] = t1[i] ;
    	rep(i , 1 , cnt2) q[ql + cnt1 + i - 1] = t2[i] ;
    	solve(l , mid , ql , ql + cnt1 - 1) ;
    	solve(mid + 1 , r , ql + cnt1 , qr) ;
    }
    signed main() {
    #ifdef _WIN64
    	freopen("testdata.in" , "r" , stdin) ;
    #endif
    	in >> n >> m ;
    	rep(i , 1 , n) rep(j , 1 , n) { int k ; in >> k ; a[++ mcnt] = { i , j , k } ; }
    	rep(i , 1 , m) { in >> q[i].x >> q[i].y >> q[i].x2 >> q[i].y2 >> q[i].k ; q[i].id = i ; }
    	sort(a + 1 , a + mcnt + 1 , [](point x , point y) { return x.val < y.val ; }) ;
    	solve(1 , mcnt , 1 , m) ; rep(i , 1 , m) out << ans[i] << '
    ' ;
    	return out.flush(), 0;
    }
    
  • 相关阅读:
    Python 01 Python的安装和配置
    Python 04 Geany的安装和配置
    Python 02 编写代码
    Python 03 pip 的安装和使用
    开源项目 12 ServiceStack.OrmLite
    北京第二天
    exit
    北京第一天
    关于扩展欧几里得算法和逆元
    正妹吃月饼
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12193400.html
Copyright © 2020-2023  润新知