社区讨论
整体二分求卡常
P1527[国家集训队] 矩阵乘法参与者 3已保存回复 7
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 6 条
- 当前快照
- 1 份
- 快照标识符
- @mko0fcgo
- 此快照首次捕获于
- 2026/01/21 20:39 2 个月前
- 此快照最后确认于
- 2026/01/22 16:12 2 个月前
40 pts ,剩下 TLE
CPP#include<bits/stdc++.h>
using namespace std;
class BIT2D
{
private:
int n,m;
int tree[505][505];
int lowbit(int x)
{
return x&-x;
}
public:
BIT2D(int _n,int _m)
{
//tree.resize(_n,vector<int>(_m));
n=_n,m=_m;
}
void add(int x,int y,int k)
{
for(int i=x;i<=n;i+=lowbit(i))
{
for(int j=y;j<=m;j+=lowbit(j))
{
tree[i][j]+=k;
}
}
}
int query(int x,int y)
{
int ans=0;
for(int i=x;i>=1;i-=lowbit(i))
{
for(int j=y;j>=1;j-=lowbit(j))
{
ans+=tree[i][j];
}
}
return ans;
}
};
struct idc
{
int x,y,k;
bool friend operator<(idc a,idc b)
{
return a.k<b.k;
}
};
struct query
{
int a,b,c,d,k;
};
int n,q,cnt=0;
idc arr[250010];
query Q[60005];
int ans[60005];
BIT2D t(505,505);
void getans(int a[],int sz,int l,int r)
{
if(sz<=0) return;
if(l==r)
{
for(int i=1;i<=sz;i++)
{
ans[a[i]]=arr[l].k;
}
return;
}
int lsz=0,rsz=0;
int larr[60005]={0};
int rarr[60005]={0};
int mid=(l+r)>>1;
for(int i=l;i<=mid;i++)
{
t.add(arr[i].x,arr[i].y,1);
}
for(int j=1;j<=sz;j++)
{
int i=a[j];
int sum=t.query(Q[i].c,Q[i].d)-t.query(Q[i].c,Q[i].b-1)-t\
.query(Q[i].a-1,Q[i].d)+t.query(Q[i].a-1,Q[i].b-1);
if(sum>=Q[i].k)
{
larr[++lsz]=i;
}
else
{
rarr[++rsz]=i;
Q[i].k-=sum;
}
}
for(int i=l;i<=mid;i++)
{
t.add(arr[i].x,arr[i].y,-1);
}
getans(larr,lsz,l,mid);
getans(rarr,rsz,mid+1,r);
}
inline void read(int& x)
{
x=0;
char ch=getchar_unlocked();
bool flag=false;
while(ch<'0' || ch>'9')
{
if(ch=='-') flag=1;
ch=getchar_unlocked();
}
while(ch>='0' && ch<='9')
{
x=x*10+ch-'0';
ch=getchar_unlocked();
}
if(flag) x=-x;
}
inline void write(int x)
{
if(x<0)
{
putchar_unlocked('-');
x=-x;
}
if(x>9) write(x/10);
putchar_unlocked(x%10+'0');
}
signed main()
{
read(n);read(q);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
read(arr[++cnt].k);
arr[cnt].x=i;
arr[cnt].y=j;
}
}
for(int i=1;i<=q;i++)
{
read(Q[i].a);
read(Q[i].b);
read(Q[i].c);
read(Q[i].d);
read(Q[i].k);
}
sort(arr+1,arr+1+cnt);
int a[60005]={0};
for(int i=1;i<=q;i++)
{
a[i]=i;
}
getans(a,q,1,cnt);
for(int i=1;i<=q;i++)
{
write(ans[i]);
putchar('\n');
}
return 0;
}
回复
共 7 条回复,欢迎继续交流。
正在加载回复...