對所有數先排序然後每次插入n個數,然後處理每個詢問
如果子矩陣中的數大於k則一定答案一定在這n個數當中,然後暴力查詢
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define n 633333
using namespace std;
int sc()
while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
return i*f;
}struct qq[n];
struct wb[n];
int a[505][505],sum[505][505];
int n,m,mx,cnt,fa[n];
int find(int
x)bool cmp(w a,w b)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
sum[i][j]=a[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
for(int i=find(1);i<=m;i=find(i+1))
fa[i]=i+1;}}
for(int i=1;i<=m;i++)printf("%d\n",q[i].ans);
return
0;}
整體二分加樹狀陣列的做法非常經典
orz_fqk神犇
(以下**是他的,不過我修改了乙個地方,在二分的時候可以嚴格按照原區間成半二分,這樣會快一點)
#include
#include
#include
#include
#define inf 1000000007
using namespace std;
int n,q,now,cnt;
int tree[505][505];
struct node a[250005];
int ans[60005];
struct query q[60005],q1[60005],q2[60005];
inline int
read()
while (c>='0'&&c<='9')
return a*f;
}inline int lowbit(int i)
inline bool operator<(node a,node b)
inline int query(int
x,int
y)void solve(int t,int w,int l,int r)
int mid=l+r>>1;
while (a[now].z<=a[mid].z) now++,add(a[now].x,a[now].y,1);
while (a[now].z>a[mid].z) add(a[now].x,a[now].y,-1),now--;
int p1=0,p2=0;
for (int i=t;i<=w;i++)
for (int i=1;i<=p1;i++) q[t+i-1]=q1[i];
for (int i=1;i<=p2;i++) q[t+p1+i-1]=q2[i];
solve(t,t+p1-1,l,mid); solve(t+p1,w,mid+1,r);
}int main()
BZOJ 2738 矩陣乘法 分塊
標算整體二分,然而窩太弱了並不會做。我們把n n個數排序,然後從小到大插入矩陣,每次插n個,用字首和維護每個子矩陣當前已經填了多少個數。查詢的時候 對於每個詢問,如果子矩陣裡的數已經超過了k個,說明答案在當前插入的這n個數里,倒著查詢即可。用鍊錶維護詢問,已經出解的直接跳過。因為每個詢問最多會查n次...
BZOJ 2738 矩陣乘法
卡時卡的我心塞啊 因為插入操作太多而且沒有順序我們需要在sort後的插入操作上滾來滾去 其實並不需要排序opt陣列,而用int下標排序可避免複製的時間過長。include include include include include define maxn 510 using namespace ...
bzoj2738 矩陣乘法
time limit 20 sec memory limit 256 mb submit 1183 solved 504 submit status discuss 給你乙個n n的矩陣,不用算矩陣乘法,但是每次詢問乙個子矩形的第k小數。第一行兩個數n,q,表示矩陣大小和詢問組數 接下來n行n列一共...