# [bzoj2639]矩形计算——二维莫队or四维数点

0 篇文章 0 订阅
5 篇文章 0 订阅

### 思路：

#include<bits/stdc++.h>

#define REP(i,a,b) for(int i=a,i##_end_=b;i<=i##_end_;++i)
#define y1 fuckyou
#define pii pair<int,int>
#define fi first
#define se second
#define mk make_pair
typedef long long ll;

using namespace std;

void File(){
freopen("bzoj2639.in","r",stdin);
freopen("bzoj2639.out","w",stdout);
}

T __=0,mul=1; char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')mul=-1;
ch=getchar();
}
while(isdigit(ch))__=(__<<1)+(__<<3)+(ch^'0'),ch=getchar();
_=__*mul;
}

const int maxn=200+10;
const int maxm=1e5+10;
int n,m,q,a[maxn][maxn],b[maxn*maxn],tot,ans[maxm];
vector<pii>pos[maxn*maxn];
int lim=100,sum[maxn<<1][maxn][maxn],cnt,vis[maxn*maxn];

struct BIT{
int s[maxn<<1][maxn][maxn];
int lowbit(int x){return x&(-x);}
for(int i=x;i<=m;i+=lowbit(i))
for(int j=y;j<=n;j+=lowbit(j))
for(int k=z;k<=m;k+=lowbit(k))
++s[i][j][k];
}
int query(int x,int y,int z){
int ret=0;
for(int i=x;i>=1;i-=lowbit(i))
for(int j=y;j>=1;j-=lowbit(j))
for(int k=z;k>=1;k-=lowbit(k))
ret+=s[i][j][k];
return ret;
}
}T;

void init(){
sort(b+1,b+tot+1);
tot=unique(b+1,b+tot+1)-b-1;
REP(i,1,n)REP(j,1,m)a[i][j]=lower_bound(b+1,b+tot+1,a[i][j])-b;
REP(i,1,n)REP(j,1,m)pos[a[i][j]].push_back(mk(i,j));
REP(i,1,n)REP(j,1,m)if(!vis[a[i][j]] && (int)pos[a[i][j]].size()>lim){
vis[a[i][j]]=1;
++cnt;
REP(f,1,n)REP(g,1,m)
sum[cnt][f][g]=sum[cnt][f-1][g]+sum[cnt][f][g-1]-sum[cnt][f-1][g-1]+(a[f][g]==a[i][j]);
pos[a[i][j]].clear();
}
}

int cnt_n;

struct node{
int x1,y1,x2,y2,id;
bool operator < (const node & tt) const {
return x1>tt.x1;
}

void work(){
REP(i,1,n)REP(j,1,m)if(!vis[a[i][j]]){
int id=a[i][j];
vis[id]=1;
//cout<<id<<endl;
REP(f,0,pos[id].size()-1){
REP(g,0,pos[id].size()-1){
int x1=min(pos[id][f].fi,pos[id][g].fi);
int x2=max(pos[id][f].fi,pos[id][g].fi);
int y1=min(pos[id][f].se,pos[id][g].se);
int y2=max(pos[id][f].se,pos[id][g].se);
//cout<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<endl;
nod[++cnt_n]=(node){x1,y1,x2,y2,0};
}
}
//cout<<"------------"<<endl;
}
sort(nod+1,nod+cnt_n+1);
int p=1;
REP(i,1,q){
(sum[j][x2][y2]-sum[j][x1-1][y2]-sum[j][x2][y1-1]+sum[j][x1-1][y1-1])
*(sum[j][x2][y2]-sum[j][x1-1][y2]-sum[j][x2][y1-1]+sum[j][x1-1][y1-1]);
//cout<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<endl;
}
REP(i,1,q)printf("%d\n",ans[i]);
}

int main(){
File();
init();
work();
cerr<<(double)clock()/CLOCKS_PER_SEC<<endl;
return 0;
}


• 0
点赞
• 0
评论
• 0
收藏
• 打赏
• 扫一扫，分享海报

09-24 122

06-18 233
05-06 37
02-28 857
09-24 247
09-24 51
11-08 401
04-18 521
09-19 492
11-21 2307
09-28 299
02-08 1705

ylsoi

¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。