Pagini recente » Cod sursa (job #2352729) | Cod sursa (job #1082916) | Cod sursa (job #895905) | Cod sursa (job #3135306) | Cod sursa (job #317677)
Cod sursa(job #317677)
#include <cstdio>
#include <algorithm>
using namespace std;
const int NMAX=303;
const int QMAX=20002;
const int HMAX=1000001;
int N,Q;
struct Query{
int x1,y1,x2,y2;
} I[QMAX];
int Sol[QMAX],t[NMAX*NMAX],b[NMAX][NMAX];
pair<int,int> tmp[QMAX],a[NMAX*NMAX];
bool U[NMAX*NMAX];
int find(int x){
if (x!=t[x]) t[x]=find(t[x]);//path compresion with style :D
else return x;
}
void unite(int x,int y){
x=find(x);y=find(y);
if (!U[y]) return;//Unim decat doua componennte ce au fost deja analizate
if ((rand()&1)) t[x]=y;
else t[y]=x;
}
int main(){
int i,j,k;
freopen("matrice2.in","r",stdin);
freopen("matrice2.out","w",stdout);
scanf("%d %d",&N,&Q);
for (i=0;i<N;++i)
for (j=0;j<N;++j){
scanf("%d",&k);
b[i][j]=k;
a[i*N+j].first=k;
a[i*N+j].second=i*N+j;
}
sort(a,a+N*N);
int x1,y1,x2,y2;
for (i=1;i<=Q;++i){
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
--x1,--x2,--y1,--y2;
I[i].x1=x1,I[i].y1=y1,I[i].x2=x2,I[i].y2=y2;
}
//O "cautare binara" (cu sau fara "") in paralel pt fiecare Query
for (k=1;k<=HMAX;k<<=1);
for (k>>=1;k>=1;k>>=1)
{
for (i=1;i<=Q;++i)
tmp[i].first=Sol[i]+k,
tmp[i].second=i;
sort(tmp+1,tmp+Q+1);
for (i=0;i<N*N;++i)
t[i]=i,U[i]=false;
for (j=Q,i=N*N-1;i>=0;--i)
{
U[a[i].second]=true;
if (a[i].first<tmp[j].first)
while (j>0 && tmp[j].first>a[i].first)
{
int idx=tmp[j].second;
if (find(I[idx].x1*N+I[idx].y1)==
find(I[idx].x2*N+I[idx].y2))
Sol[idx]+=k;
--j;
}
int _x,_y;
_x=a[i].second/N;
_y=a[i].second%N;
if (_x>0 && b[_x-1][_y]>=a[i].first)
unite(a[i].second,(_x-1)*N+_y);
if (_x+1<N && b[_x+1][_y]>=a[i].first)
unite(a[i].second,(_x+1)*N+_y);
if (_y>0 && b[_x][_y-1]>=a[i].first)
unite(a[i].second,_x*N+_y-1);
if (_y+1<N && b[_x][_y+1]>=a[i].first)
unite(a[i].second,_x*N+_y+1);
}
while (j>0 )
{
int idx=tmp[j].second;
if (find(I[idx].x1*N+I[idx].y1)==
find(I[idx].x2*N+I[idx].y2))
Sol[idx]+=k;
--j;
}
}
for (i=1;i<=Q;++i)
printf("%d\n",Sol[i]);
return 0;
}