1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| #include<cstdio> #include<algorithm> #include<ctype.h> #include<string.h> #include<math.h>
using namespace std; #define ll long long
inline char read() { static const int IN_LEN = 1000000; static char buf[IN_LEN], *s, *t; return (s == t ? t = (s = buf) + fread(buf, 1, IN_LEN, stdin), (s == t ? -1 : *s++) : *s++); } template<class T> inline void read(T &x) { static bool iosig; static char c; for (iosig = false, c = read(); !isdigit(c); c = read()) { if (c == '-') iosig = true; if (c == -1) return; } for (x = 0; isdigit(c); c = read()) x = ((x + (x << 2)) << 1) + (c ^ '0'); if (iosig) x = -x; } const int OUT_LEN = 10000000; char obuf[OUT_LEN], *ooh = obuf; inline void print(char c) { if (ooh == obuf + OUT_LEN) fwrite(obuf, 1, OUT_LEN, stdout), ooh = obuf; *ooh++ = c; } template<class T> inline void print(T x) { static int buf[30], cnt; if (x == 0) print('0'); else { if (x < 0) print('-'), x = -x; for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 + 48; while (cnt) print((char)buf[cnt--]); } } inline void flush() { fwrite(obuf, 1, ooh - obuf, stdout); } const int N = 202, M = 40005, Q = 100005, K = 16; int n, m, q, cnt, id, sn, sm, x, y, xx, yy, ans, b[K][K], a[N][N], rk[N][N], d[M], Ans[Q]; pair<int,int*> p[M]; struct query{ int x, y, xx, yy, id; inline void input(){ read(x), read(y), read(xx), read(yy); if(x>xx) swap(x, xx); if(y>yy) swap(y, yy); } inline bool operator <(const query &rhs)const{ return rk[x][y]!=rk[rhs.x][rhs.y]?rk[x][y]<rk[rhs.x][rhs.y]:rk[xx][yy]<rk[rhs.xx][rhs.yy];} } s[Q]; void insl(int x){ for(int i=y; i<=yy; ++i) ans+=2*d[a[x][i]]+++1;} void dell(int x){ for(int i=y; i<=yy; ++i) ans-=2*d[a[x][i]]---1;} void insc(int y){ for(int i=x; i<=xx; ++i) ans+=2*d[a[i][y]]+++1;} void delc(int y){ for(int i=x; i<=xx; ++i) ans-=2*d[a[i][y]]---1;} int main() { read(n), read(m); for(int i=1; i<=n; ++i) for(int j=1; j<=m; ++j) read(a[i][j]), p[++cnt]=make_pair(a[i][j], &a[i][j]); sort(p+1, p+cnt+1); for(int i=1; i<=cnt; ++i) *(p[i].second)=(p[i].first==p[i-1].first?id:++id); sn=sqrt(n), sm=sqrt(m), id=0; for(int i=1; i<=(n-1)/sn+1; ++i){ if(i&1) for(int j=1; j<=(m-1)/sm+1; ++j) b[i][j]=++id; else for(int j=(m-1)/sm+1; j; --j) b[i][j]=++id; } for(int i=1; i<=n; ++i) for(int j=1; j<=m; ++j) rk[i][j]=b[(i-1)/sn+1][(j-1)/sm+1]; read(q); for(int i=1; i<=q; ++i) s[i].input(), s[i].id=i; sort(s+1, s+q+1); x=1, y=1, xx=0, yy=0; for(int i=1; i<=q; ++i){ while(x>s[i].x) insl(--x); while(xx<s[i].xx) insl(++xx); while(y>s[i].y) insc(--y); while(yy<s[i].yy) insc(++yy); while(x<s[i].x) dell(x++); while(xx>s[i].xx) dell(xx--); while(y<s[i].y) delc(y++); while(yy>s[i].yy) delc(yy--); Ans[s[i].id]=ans; } for(int i=1; i<=q; ++i) print(Ans[i]), print('\n'); return flush(), 0; }
|