您的位置:首页 > 其它

[BZOJ 2738]矩阵乘法

2016-02-19 11:35 465 查看
卡时卡的我心塞啊

因为插入操作太多而且没有顺序我们需要在sort后的插入操作上滚来滚去= =

其实并不需要排序opt数组,而用int下标排序可避免复制的时间过长。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <ctime>
#define maxn 510
using namespace std;

void read(int &num){
	num = 0;char ch = getchar();
	for(;ch < '!'; ch = getchar());
	for(;ch > '!'; ch = getchar())
		num = num * 10 + ch - 48;
}
int N, Q;
//BIT{
	int t[maxn][maxn];
	int lowbit[maxn];
	#define lowbit_cal(x) (x & ((~x) + 1))

	void update(int x, int y, const int& val){
		if(!x || !y)return;
		int tmp = y;
		while(x <= N){
			y = tmp;
			while(y <= N){
				t[x][y] += val;
				y += lowbit_cal(y);
			}
			x += lowbit_cal(x);
		}
	}
	
	int ask(int x, int y){
        if(!x || !y)return 0;
		int tmp = y, ans = 0;
		while(x){
			y = tmp;
			while(y){
				ans += t[x][y];
				y -= lowbit_cal(y);
			}
			x -= lowbit_cal(x);
		}
		return ans;
	}
	
	int ask(const int& x1, const int& y1, const int& x2, const int& y2){
		int ans = ask(x1 - 1, y1 - 1) + ask(x2, y2);
		ans -= ask(x2, y1 - 1) + ask(x1 - 1, y2);
		return ans;
	}

int n;
#define maxq 310010
struct opt{
	int x1, y1, tp;
	int x2, y2, k;
	bool operator<(const opt& k)const{
		return tp < k.tp;
	}
}q[maxq], q1[maxq], q2[maxq];

const int inf = 0x7fffffff;

int TMP, ans[maxq];

int T = 0;

void solve(int head, int tail, int l, int r){
    //cout << head << ' ' << tail << ' ' << l << ' ' << r << endl;
	if(head > tail)return;
	if(l == r){
		for(int i = head; i <= tail; i ++)
			ans[q[i].tp] = l;
		return;
	}
	int mid = l + r >> 1;
	while(q[T + 1].tp <= mid && T < TMP)
	    T ++, update(q[T].x1, q[T].y1, 1);
	while(q[T].tp > mid && T)
	    update(q[T].x1, q[T].y1, -1), T --;

	int l1 = 0, l2 = 0;
	for(int i = head; i <= tail; i ++){
		if(ask(q[i].x1, q[i].y1, q[i].x2, q[i].y2) >= q[i].k)
			q1[++ l1] = q[i];
		else{
			//q[i].k -= tmp[i];
			q2[++ l2] = q[i];
		}
	}
	
	int cnt = head;
	for(int i = 1; i <= l1; i ++)q[cnt ++] = q1[i];
	for(int i = 1; i <= l2; i ++)q[cnt ++] = q2[i];

//	memcpy(q + head, q1 + 1, sizeof (q[0]) * l1);
//	memcpy(q + head + l1, q2 + 1, sizeof (q[0]) * l2);
	solve(head, head + l1 - 1, l, mid);
	solve(head + l1, tail, mid + 1, r);
}

int main(){
    freopen("nt2012_mat.in","r",stdin);
	freopen("nt2012_mat.out","w",stdout);
	
	read(N);
	read(Q);
	TMP = N * N;

	int x;
	int mn = inf, mx = -inf;

	for(int i = 1; i <= N; i ++){
		for(int j = 1; j <= N; j ++){
			read(x);
	        if(x < mn)mn = x;
			if(x > mx)mx = x;
			++ n;
			q
.x1 = i;
			q
.y1 = j;
			q
.tp = x;
		}
	}
	sort(q + 1, q + 1 + n);

	int id = 0;
	for(int i = 1; i <= Q; i ++){
		++ n;
		read(q
.x1), read(q
.y1);
		read(q
.x2), read(q
.y2);
		read(q
.k);
		q
.tp = ++ id;
	}
	solve(TMP + 1, n, mn, mx);
   
	for(int i = 1; i <= Q; i ++)
		printf("%d\n", ans[i]);
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: