[BZOJ2738]矩阵乘法(梁盾)CDQ分治+二维树状数组

来源:互联网 发布:windows mdt是什么意思 编辑:程序博客网 时间:2024/06/05 11:41

将矩阵内所有数字从小到大排序依次加入

判断询问集合S内的matrix中数字个数是否大于等于k,如果是,修改该matrix的ans

同时将询问集合二分

时间代价q logq logn logn

第一次拿viante的名字开变量名,第一次1ACDQ分治


#include <iostream>#include <cstdio>#include <algorithm>#include <vector> #define N 1000050using namespace std; inline 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;} int n,q,cnt; struct Que{ int x1,y1,x2,y2,k,ans; }Q[N];struct Map{ int x,y,v; }map[N];bool operator < (Map p1,Map p2) { return p1.v < p2.v; }inline int lowbit(int x) { return (x & (-x)); }struct Small_Segment_Tree{int tr[550][550];inline void add(int x,int y,int v) {for (int i=x;i<=n;i+=lowbit(i))for (int j=y;j<=n;j+=lowbit(j))tr[i][j] += v;}inline int ask(int x,int y) {int tmp = 0;for (int i=x;i;i-=lowbit(i))for (int j=y;j;j-=lowbit(j))tmp += tr[i][j];return tmp;}inline int query(Que p) {return ask(p.x2,p.y2) - ask(p.x1-1,p.y2) - ask(p.x2,p.y1-1) + ask(p.x1-1,p.y1-1);}}T;inline void init() {n = read(); q = read();    for (int i=1;i<=n;i++)        for (int j=1;j<=n;j++) {        map[++cnt].v = read();        map[cnt].x = i;        map[cnt].y = j;        }            for (int i=1;i<=q;i++) {    Q[i].x1 = read();Q[i].y1 = read();;Q[i].x2 = read();Q[i].y2 = read();Q[i].k = read();}}int viante = 1;void solve(int l,int r,vector<int> S) {if (!S.size()) return;for (int i=0;i<S.size();i++) Q[S[i]].ans = map[r].v;if (l == r) return ;int mid = (l + r) >> 1;while (viante <= mid) T.add(map[viante].x,map[viante].y,1) , viante++;while (viante > mid+1) viante-- , T.add(map[viante].x,map[viante].y,-1);vector<int> S1,S2;for (int i=0;i<S.size();i++) {int t = S[i];if (T.query(Q[t]) >= Q[t].k) {//printf("1 %d\n",t);S1.push_back(t);} else {//printf("2 %d\n",t);S2.push_back(t);} }solve(l,mid,S1); solve(mid+1,r,S2);return ;} int main(){    init();    sort(map+1,map+n*n+1);    vector<int> S;    for (int i=1;i<=q;i++) S.push_back(i);    solve(1,cnt,S);    for (int i=1;i<=q;i++) printf("%d\n",Q[i].ans);    return 0;}


0 0
原创粉丝点击