【BZOJ2639】矩形计算(二维普通莫队)

题意:输入一个n*m的矩阵,矩阵的每一个元素都是一个整数,然后有q个询问,每次询问一个子矩阵的权值。

矩阵的权值是这样定义的,对于一个整数x,如果它在该矩阵中出现了p次,那么它给该矩阵的权值就贡献p^2。

n,m<=200,m<=1e5,abs(a[i][j])<=2e9

思路:学习资料见https://www.cnblogs.com/ouuan/p/2DMoDui.html

和一维普通莫队差不多,先扩大区间再缩小保证不会出错

这个块长很有特色,和n,m,q都有关

map离散化真的不靠谱,换预处理离散化即可

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef pair<int,int> PII;
  7 typedef pair<ll,ll> Pll;
  8 typedef vector<int> VI;
  9 typedef vector<PII> VII;
 10 //typedef pair<ll,ll>P;
 11 #define N  210
 12 #define M  200010
 13 #define fi first
 14 #define se second
 15 #define MP make_pair
 16 #define pb push_back
 17 #define pi acos(-1)
 18 #define mem(a,b) memset(a,b,sizeof(a))
 19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 21 #define lowbit(x) x&(-x)
 22 #define Rand (rand()*(1<<16)+rand())
 23 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 24 #define ls p<<1
 25 #define rs p<<1|1
 26 
 27 const int MOD=1e9+7,inv2=(MOD+1)/2;
 28       double eps=1e-4;
 29       int INF=1e9;
 30       int inf=0x7fffffff;
 31       int dx[4]={-1,1,0,0};
 32       int dy[4]={0,0,-1,1};
 33 
 34 struct Q
 35 {
 36     int x1,y1,x2,y2,id;
 37 }t[M];
 38 
 39 int cnt[N*N],c[N*N];
 40 int ans[M],pos[250],a[N][N],sum,L1,L2,R1,R2;
 41 
 42 int read()
 43 {
 44    int v=0,f=1;
 45    char c=getchar();
 46    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 47    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 48    return v*f;
 49 }
 50 
 51 bool cmp(Q a,Q b)
 52 {
 53     return pos[a.x1]<pos[b.x1]
 54          ||pos[a.x1]==pos[b.x1]&&pos[a.y1]<pos[b.y1]
 55          ||pos[a.x1]==pos[b.x1]&&pos[a.y1]==pos[b.y1]&&pos[a.x2]<pos[b.x2]
 56          ||pos[a.x1]==pos[b.x1]&&pos[a.y1]==pos[b.y1]&&pos[a.x2]==pos[b.x2]&&pos[a.y2]<pos[b.y2];
 57 }
 58 
 59 void add(int op,int x,int y,int z)
 60 {
 61     if(op==1)
 62     {
 63         if(!x) return;
 64         rep(j,y,z)
 65          if(j)
 66          {
 67             sum+=(cnt[a[x][j]]<<1)+1;
 68             cnt[a[x][j]]++;
 69          }
 70     }
 71      else
 72      {
 73          if(!z) return;
 74          rep(i,x,y)
 75           if(i)
 76           {
 77               sum+=(cnt[a[i][z]]<<1)+1;
 78               cnt[a[i][z]]++;
 79           }
 80      }
 81 }
 82 
 83 void del(int op,int x,int y,int z)
 84 {
 85     if(op==1)
 86     {
 87         if(!x) return;
 88         rep(j,y,z)
 89          if(j)
 90          {
 91              sum=sum-(cnt[a[x][j]]<<1)+1;
 92              cnt[a[x][j]]--;
 93          }
 94     }
 95      else
 96      {
 97          if(!z) return;
 98          rep(i,x,y)
 99           if(i)
100           {
101               sum=sum-(cnt[a[i][z]]<<1)+1;
102               cnt[a[i][z]]--;
103           }
104      }
105 }
106 
107 int main()
108 {
109     int n=read(),m=read();
110     int tot=0;
111     rep(i,1,n)
112      rep(j,1,m)
113      {
114          a[i][j]=read();
115          c[++tot]=a[i][j];
116      }
117     sort(c+1,c+tot+1);
118     int k=unique(c+1,c+tot+1)-c-1;
119     rep(i,1,n)
120      rep(j,1,m) a[i][j]=lower_bound(c+1,c+k+1,a[i][j])-c;
121     int q=read();
122     int S=pow(n*m,0.5)/pow(q,0.25)+1;
123     rep(i,1,200) pos[i]=(i-1)/S;
124     rep(i,1,q)
125     {
126         int x1=read(),y1=read(),x2=read(),y2=read();
127         t[i].x1=min(x1,x2);
128         t[i].x2=max(x1,x2);
129         t[i].y1=min(y1,y2);
130         t[i].y2=max(y1,y2);
131         t[i].id=i;
132     }
133     sort(t+1,t+q+1,cmp);
134     L1=0,L2=0,R1=0,R2=0;
135     sum=0;
136     rep(i,1,q)
137     {
138         while(L1>t[i].x1)
139         {
140             L1--;
141             add(1,L1,R1,R2);
142         }
143         while(L2<t[i].x2)
144         {
145             L2++;
146             add(1,L2,R1,R2);
147         }
148         while(R1>t[i].y1)
149         {
150             R1--;
151             add(2,L1,L2,R1);
152         }
153         while(R2<t[i].y2)
154         {
155             R2++;
156             add(2,L1,L2,R2);
157         }
158 
159         while(L1<t[i].x1)
160         {
161             del(1,L1,R1,R2);
162             L1++;
163         }
164         while(L2>t[i].x2)
165         {
166             del(1,L2,R1,R2);
167             L2--;
168         }
169         while(R1<t[i].y1)
170         {
171             del(2,L1,L2,R1);
172             R1++;
173         }
174         while(R2>t[i].y2)
175         {
176             del(2,L1,L2,R2);
177             R2--;
178         }
179         ans[t[i].id]=sum;
180     }
181     rep(i,1,q) printf("%d
",ans[i]);
182     return 0;
183 }
原文地址:https://www.cnblogs.com/myx12345/p/11643941.html