首页 > 其他分享 >P1527 [国家集训队] 矩阵乘法

P1527 [国家集训队] 矩阵乘法

时间:2023-12-13 17:00:28浏览次数:30  
标签:P1527 short r1 r2 Cpt l2 l1 国家集训队 乘法

题意

给定一个矩阵,每次询问子矩阵的第 \(k\) 大。

Sol

考虑把莫队扔到二维上来做。

发现复杂度变为:\(O(n ^ 2 q ^ {\frac {3}{4}})\)。

卡卡常就过了。

Code

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <array>
#include <cmath>
#include <vector>
#include <cassert>
#define il inline
#define rg register
using namespace std;
#ifdef ONLINE_JUDGE

#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf;

#endif
int read() {
    int p = 0, flg = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-') flg = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        p = p * 10 + c - '0';
        c = getchar();
    }
    return p * flg;
}
void write(int x) {
    if (x < 0) {
        x = -x;
        putchar('-');
    }
    if (x > 9) {
        write(x / 10);
    }
    putchar(x % 10 + '0');
}

const int N = 505, M = 2.5e5 + 5;
array <array <int, N>, N> mp;

namespace Cpt {

short bsi = 11;

array <short, M> agc;

class Node {

public:
    short l1, r1, l2, r2;
    int k, id;

    Node () : l1(), r1(), l2(), r2(), k(), id() {}

    Node (short _l1, short _l2, short _r1, short _r2, int _k, int _id) {
        l1 = _l1, r1 = _r1, l2 = _l2, r2 = _r2, k = _k, id = _id;
    }

    il bool operator <(const Node &t) const {
        if (agc[l1] != agc[t.l1]) return l1 < t.l1;
        if (agc[l2] != agc[t.l2]) return (agc[l1]) & 1 ? l2 < t.l2 : l2 > t.l2;
        if (agc[r2] != agc[t.r2]) return (agc[l2]) & 1 ? r2 < t.r2 : r2 > t.r2;
        else return (agc[r2]) & 1 ? r1 < t.r1 : r1 > t.r1;
        // if (l1 / bsi != t.l1 / bsi) return l1 < t.l1;
        // if (r1 / bsi != t.r1 / bsi) return (l1 / bsi) & 1 ? r1 < t.r1 : r1 > t.r1;
        // if (r2 / bsi != t.r2 / bsi) return (r1 / bsi) & 1 ? r2 < t.r2 : r2 > t.r2;
        // else return (r2 / bsi) & 1 ? l2 < t.l2 : l2 > t.l2;
    }

};

array <Node, M> edge;

namespace Blk {

short bsi = 610;

array <int, M> cur;
array <int, N> bk;

array <int, M> arc;

il int calc(int x) {
    return (x - 1) / bsi + 1;
}

il void modify(int x, short y) { cur[x] += y, bk[arc[x]] += y; }

il int query(int k) {
    rg short tot = 0;
    for (rg short i = 1; i <= 500; i++) {
        if (k - bk[i] <= 0) {
            tot = i;
            break;
        }
        k -= bk[i];
    }
    rg int ans = 0;
    for (rg int i = (tot - 1) * bsi + 1; i <= min(tot * bsi, (int)2.5e5); i++) {
        k -= (int)cur[i];
        if (k <= 0) {
            ans = i;
            break;
        }
    }
    // assert(ans >= 0);
    return ans;
}

}

il void modify(short x1, short x2, short y1, short y2, short k) {
    for (rg short i = x1; i <= x2; i++)
        for (rg short j = y1; j <= y2; j++)
            Blk::modify(mp[i][j], k);
}

}

vector <int> isl;
array <int, M> ans;

int main() {
    rg int n = read(), m = read();
    Cpt::bsi = n / pow(m, 0.25) / 3 + 1;
    Cpt::Blk::bsi = n + 1;
    for (short i = 1; i <= n; i++) Cpt::agc[i] = (i - 1) / Cpt::bsi + 1;
    for (int i = 1; i <= n * n; i++) Cpt::Blk::arc[i] = (i - 1) / Cpt::Blk::bsi + 1;
    for (rg short i = 1; i <= n; i++)
        for (rg short j = 1; j <= n; j++)
            mp[i][j] = read(), isl.push_back(mp[i][j]);
    sort(isl.begin(), isl.end());
    isl.erase(unique(isl.begin(), isl.end()), isl.end());
    for (rg short i = 1; i <= n; i++)
        for (rg short j = 1; j <= n; j++)
            mp[i][j] = lower_bound(isl.begin(), isl.end(), mp[i][j]) - isl.begin() + 1;
    // for (int i = 1; i <= n; i++) {
    //     for (int j = 1; j <= n; j++)
    //         write(mp[i][j]), putchar(32);
    //     puts("");
    // }
    for (rg int i = 1; i <= m; i++) {
        rg short x1 = read(), y1 = read(), x2 = read(), y2 = read();
        rg int k = read();
        Cpt::edge[i] = Cpt::Node(x1, y1, x2, y2, k, i);
    }
    sort(Cpt::edge.begin() + 1, Cpt::edge.begin() + 1 + m);
    rg short l1 = 1, l2 = 1, r1 = 1, r2 = 1; Cpt::Blk::cur[mp[1][1]]++, Cpt::Blk::bk[Cpt::Blk::calc(mp[1][1])]++;
    for (int i = 1; i <= m; i++) {
        rg short x1 = Cpt::edge[i].l1, x2 = Cpt::edge[i].l2,
                y1 = Cpt::edge[i].r1, y2 = Cpt::edge[i].r2;
        // write(x1), putchar(32);
        // write(y1), puts("@");
        while (l1 > x1) l1--, Cpt::modify(l1, l1, l2, r2, 1);
        while (l2 > x2) l2--, Cpt::modify(l1, r1, l2, l2, 1);
        while (r1 < y1) r1++, Cpt::modify(r1, r1, l2, r2, 1);
        while (r2 < y2) r2++, Cpt::modify(l1, r1, r2, r2, 1);
        while (l1 < x1) Cpt::modify(l1, l1, l2, r2, -1), l1++;
        while (l2 < x2) Cpt::modify(l1, r1, l2, l2, -1), l2++;
        while (r1 > y1) Cpt::modify(r1, r1, l2, r2, -1), r1--;
        while (r2 > y2) Cpt::modify(l1, r1, r2, r2, -1), r2--;
        ans[Cpt::edge[i].id] = Cpt::Blk::query(Cpt::edge[i].k);
    }
    for (rg int i = 1; i <= m; i++) {
        // assert(ans[i] > -2);
        write(isl[ans[i] - 1]), puts("");
    }
    return 0;
}

标签:P1527,short,r1,r2,Cpt,l2,l1,国家集训队,乘法
From: https://www.cnblogs.com/cxqghzj/p/17899455.html

相关文章

  • Day26 打印九九乘法表
    打印九九乘法表分以下几步执行:1.我们先打印第一列,这个家应该都会2.我们把固定的1再用一个循环包起米3.去掉重复项,i<=j4.调整样式1.打印第一列packagecom.baixiaofan.struct;/*1*1=11*2=22*2=41*3=32*3=63*3=91*4=42*4=83*4=124*4=161*5=52*5=1......
  • 学C笔记归纳 第九篇——分支循环语句3_for_while_do while(附九九乘法表解析和三种方式
     基础语法模版:while(1 条件控制语句){2 语句序列;}顺序:121212....21 do{ 1语句序列; }while(2 循环控制表达式);顺序:121212....12  for(1 初始化表达式;2 条件控制语句;4 调整表达式){3......
  • SQL 算术运算符:加法、减法、乘法、除法和取模的用法
    SQLServer中的存储过程什么是存储过程?存储过程是一段预先编写好的SQL代码,可以保存在数据库中以供反复使用。它允许将一系列SQL语句组合成一个逻辑单元,并为其分配一个名称,以便在需要时调用执行。存储过程可以接受参数,使其更加灵活和通用。存储过程语法创建存储过程的语法如......
  • SQL 算术运算符:加法、减法、乘法、除法和取模的用法
    SQLServer中的存储过程什么是存储过程?存储过程是一段预先编写好的SQL代码,可以保存在数据库中以供反复使用。它允许将一系列SQL语句组合成一个逻辑单元,并为其分配一个名称,以便在需要时调用执行。存储过程可以接受参数,使其更加灵活和通用。存储过程语法创建存储过程的语法......
  • 矩阵乘法运算
    代码是对整数的如果要对小数的话改个字符就OK啦用途没有就是做线性代数怕计算罢了#include<stdio.h>voidcreateMatrix(inta[10][10],intm,intn){for(inti=0;i<m;++i){for(intj=0;j<n;j++){scanf_s("%d",&a[i][j]);......
  • 矩阵乘法 - 斐波那契前 n 项和
    题目题目描述求数列\(f_n=f_{n-2}+f_{n-1}\)的前\(n\)项的和,其中\(f_1=1,f_2=1\)。输出的数\(\bmod\10^9+7\)样例样例输入10样例输出143数据范围对于\(20\%\)的数据,有\(1\leqn\leq20\)对于\(100\%\)的数据,有\(1≤n<2^{63}\)分析这道题目矩阵乘法的......
  • 秦疆的Java课程笔记:41 流程控制 打印九九乘法表
    打印九九乘法表:1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*......
  • 汇编-MUL和IMUL乘法
    32位模式下整数乘法可以实现32、16或8位的操作,64位下还可以使用64位操作数。MUL执行无符号乘法,IMUL执行有符号乘法MUL:无符号数乘法32位模式下,MUL(无符号数乘法)指令有三种类型:执行8位操作数与AL寄存器的乘法;执行16位操作数与AX寄存器的乘法;执行32位操作数与EAX寄......
  • R语言集成模型:提升树boosting、随机森林、约束最小二乘法加权平均模型融合分析时间序
    原文链接:http://tecdat.cn/?p=24148原文出处:拓端数据部落公众号 最近我们被要求撰写关于集成模型的研究报告,包括一些图形和统计输出。特别是在经济学/计量经济学中,建模者不相信他们的模型能反映现实。比如:收益率曲线并不遵循三因素的Nelson-Siegel模型,股票与其相关因素之间的......
  • C#通过循环绘制九九乘法表以及杨辉三角形
    九九乘法表 定义两个变量intx,y;for(x=1;x<=9;x++)//循环列{for(y=1;y<=x;y++)//循环行{Console.Write("{1}*{0}={2}",x,y,x*y);//显示出每一个式子}Console.WriteLine();//在每一行换行}杨辉三角形......