1. 程式人生 > >國家集訓隊 矩陣乘法

國家集訓隊 矩陣乘法

題目描述

題解:

考慮到答案具有單調性,我們將其放入二維樹狀陣列/二維線段樹即可。

程式碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 505
#define Q 60050
#define ll long long
inline int rd()
{
    int f=1,c=0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    
while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();} return f*c; } int n,m,ans[Q],mx,lp[N*N],rp[N*N],to[N*N]; struct node { int x,y,k; }p[N*N]; struct sqr { int x_,y_,_x,_y,k,id; void read() { x_ = rd(),y_ = rd(),_x = rd(),_y = rd(),k = rd(); } }q[Q],tmpl[Q],tmpr[Q];
bool cmp(node a,node b) { return a.k<b.k; } struct BIT { ll f[N][N]; void up(int x,int y,ll d) { if(!x||!y)return ; for(int i=x;i<N;i+=(i&-i)) for(int j=y;j<N;j+=(j&-j)) f[i][j]+=d; } ll down(int x,int y) {
if(!x||!y)return 0; ll ret = 0; for(int i=x;i;i-=(i&-i)) for(int j=y;j;j-=(j&-j)) ret+=f[i][j]; return ret; } }tr; void update(int k,int d) { for(int i=lp[k];i<=rp[k];i++) tr.up(p[i].x,p[i].y,d); } ll ask(int x_,int y_,int _x,int _y) { return tr.down(_x,_y)+tr.down(x_-1,y_-1)-tr.down(_x,y_-1)-tr.down(x_-1,_y); } int tim; void divi(int l,int r,int beg,int ens) { if(beg>ens)return ; if(l==r) { for(int i=beg;i<=ens;i++) ans[q[i].id] = to[l]; return ; } int mid = (l+r)>>1; while(tim<mid)tim++,update(tim,1); while(tim>mid)update(tim,-1),tim--; int lt = 0,rt = 0; for(int i=beg;i<=ens;i++) { ll sum = ask(q[i].x_,q[i].y_,q[i]._x,q[i]._y); if(sum>=q[i].k)tmpl[++lt] = q[i]; else tmpr[++rt] = q[i]; } for(int i=beg;i<=beg+lt-1;i++)q[i]=tmpl[i-beg+1]; for(int i=beg+lt;i<=ens;i++)q[i]=tmpr[i-beg-lt+1]; divi(l,mid,beg,beg+lt-1); divi(mid+1,r,beg+lt,ens); } int main() { n = rd(),m = rd(); for(int i=1;i<=n*n;i++) { p[i].x = (i-1)/n+1; p[i].y = (i-1)%n+1; p[i].k = rd(); } sort(p+1,p+1+n*n,cmp); for(int las=-1,i=1;i<=n*n;i++) { if(p[i].k!=las) { rp[mx] = i-1; las = p[i].k; mx++; lp[mx] = i; to[mx] = las; } p[i].k = mx; } rp[mx] = n*n; for(int i=1;i<=m;i++) q[i].read(),q[i].id=i; divi(1,mx+1,1,m); for(int i=1;i<=m;i++) printf("%d\n",ans[i]); return 0; }