树套树
Description
一个 \(N*M\) 的方格,初始时每个格子有一个整数权值,接下来每次有 \(2\) 个操作:
- 改变一个格子的权值
- 求一个子矩阵中某个特定权值出现的个数
Input
每一行有两个数字 \(N,M\)。接下来N行,每行 \(M\) 个数字。第 \(i+1\) 行第 \(j\) 个数字表示格子 \((i,j)\) 的初值。
接下来输入一个 \(Q\),后面 \(Q\) 行每行描述一个操作。
- 操作1:
1 x y c,表示将格子(x,y)的值变为c - 操作2:
2 x1 x2 y1 y2 c,表示询问所有满足格子中数字为c的格子数字
(n,m<=300,Q<=5000)
(1<=x<=N,1<=y<=M,1<=c<=100)
(x1<=x<=x2,y1<=y<=y2)
Output
对于每个操作 \(2\),按输入中出现的顺序,依次输出一行一个整数表示所求得的个数。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e2+5;
int n,m,q;
int v[N][N],a[105][N][N];
inline int lowbit(int x){
return x&-x;
}
void add(int c,int x,int y,int k){
for(int i=x;i<N;i+=lowbit(i))
for(int j=y;j<N;j+=lowbit(j))
a[c][i][j]+=k;
return;
}
int find(int c,int x,int y){
int res=0;
for(int i=x;i>0;i-=lowbit(i))
for(int j=y;j>0;j-=lowbit(j))
res+=a[c][i][j];
return res;
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>v[i][j];
add(v[i][j],i,j,1);
}
cin>>q;
while(q--){
int op,x,y,l,r,c;
cin>>op;
if(op==1){
cin>>x>>y>>c;
add(v[x][y],x,y,-1);
add(c,x,y,1);
v[x][y]=c;
}
if(op==2){
cin>>x>>l>>y>>r>>c;
cout<<find(c,l,r)+find(c,x-1,y-1)-find(c,l,y-1)-find(c,x-1,r)<<'\n';
}
}
return 0;
}
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e2+5;
int n,m,q;
int v[N][N];
struct tree_Y{
int a[N];
int v;
int lowbit(int x){
return x&-x;
}
tree_Y(){
memset(a,0,sizeof(a));
this->v=301;
}
void add(int x,int f){
while(x<v){
a[x]+=f;
x+=lowbit(x);
}
return;
}
int find(int x){
int res=0;
while(x>0){
res+=a[x];
x-=lowbit(x);
}
return res;
}
}a[N][N];
int lowbit(int x){
return x&-x;
}
void add(int c,int x,int y,int k){
for(int i=x;i<N;i+=lowbit(i))
a[c][i].add(y,k);
return;
}
int find(int c,int x,int y){
int res=0;
for(int i=x;i>0;i-=lowbit(i))
res+=a[c][i].find(y);
return res;
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>v[i][j];
add(v[i][j],i,j,1);
}
cin>>q;
while(q--){
int op,x,y,l,r,c;
cin>>op;
if(op==1){
cin>>x>>y>>c;
add(v[x][y],x,y,-1);
add(c,x,y,1);
v[x][y]=c;
}
if(op==2){
cin>>x>>l>>y>>r>>c;
cout<<find(c,l,r)+find(c,x-1,y-1)-find(c,l,y-1)-find(c,x-1,r)<<'\n';
}
}
return 0;
}
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e2+5;
int n,m,q;
int v[N][N];
struct tree_Y{
int a[N];
int v;
int lowbit(int x){
return x&-x;
}
tree_Y(){
memset(a,0,sizeof(a));
this->v=301;
}
void add(int x,int f){
while(x<v){
a[x]+=f;
x+=lowbit(x);
}
return;
}
int find(int x){
int res=0;
while(x>0){
res+=a[x];
x-=lowbit(x);
}
return res;
}
};
struct tree_X{
tree_Y a[N];
int v;
int lowbit(int x){
return x&-x;
}
tree_X(){
this->v=301;
}
void add(int x,int y,int f){
while(x<v){
a[x].add(y,f);
x+=lowbit(x);
}
return;
}
int find(int x,int y){
int res=0;
while(x>0){
res+=a[x].find(y);
x-=lowbit(x);
}
return res;
}
}a[N];
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>v[i][j];
a[v[i][j]].add(i,j,1);
}
cin>>q;
while(q--){
int op,x,y,l,r,c;
cin>>op;
if(op==1){
cin>>x>>y>>c;
a[v[x][y]].add(x,y,-1);
a[c].add(x,y,1);
v[x][y]=c;
}
if(op==2){
cin>>x>>l>>y>>r>>c;
cout<<a[c].find(l,r)+a[c].find(x-1,y-1)-a[c].find(l,y-1)-a[c].find(x-1,r)<<'\n';
}
}
return 0;
}
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e2+5;
int n,m,q;
int v[N][N];
struct tree_Y{
int l,r;
int sum;
tree_Y *pl,*pr;
tree_Y(int ll,int rr):l(ll),r(rr),sum(0),pl(nullptr),pr(nullptr){}
void add(int y,int k){
if(l==r){
sum+=k;
return;
}
int mid=l+r>>1;
if(y<=mid){
if(!pl) pl=new tree_Y(l,mid);
pl->add(y,k);
}
if(y>mid){
if(!pr) pr=new tree_Y(mid+1,r);
pr->add(y,k);
}
sum=(pl?pl->sum:0)+(pr?pr->sum:0);
return;
}
int query(int x,int y){
if(r<x||l>y) return 0;
if(x<=l&&r<=y) return sum;
int res=0;
if(pl) res+=pl->query(x,y);
if(pr) res+=pr->query(x,y);
return res;
}
};
struct tree_X{
int l,r;
tree_Y y_tree;
tree_X *pl,*pr;
tree_X(int ll,int rr,int m):l(ll),r(rr),y_tree(1,m),pl(nullptr),pr(nullptr){}
void add(int x,int y,int k){
if(l==r){
y_tree.add(y,k);
return;
}
int mid=l+r>>1;
if(x<=mid){
if(!pl) pl=new tree_X(l,mid,m);
pl->add(x,y,k);
}
if(x>mid){
if(!pr) pr=new tree_X(mid+1,r,m);
pr->add(x,y,k);
}
y_tree.add(y,k);
return;
}
int query(int x1,int y1,int x2,int y2){
if(r<x1||l>y1) return 0;
if(x1<=l&&r<=y1) return y_tree.query(x2,y2);
int res=0;
if(pl) res+=pl->query(x1,y1,x2,y2);
if(pr) res+=pr->query(x1,y1,x2,y2);
return res;
}
}*a[N];
signed main(){
cin>>n>>m;
for(int i=1;i<=100;i++)
a[i]=new tree_X(1,n,m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>v[i][j];
a[v[i][j]]->add(i,j,1);
}
cin>>q;
while(q--){
int op,x,y,l,r,c;
cin>>op;
if(op==1){
cin>>x>>y>>c;
a[v[x][y]]->add(x,y,-1);
a[c]->add(x,y,1);
v[x][y]=c;
}
if(op==2){
cin>>x>>l>>y>>r>>c;
cout<<a[c]->query(x,y,l,r)<<'\n';
}
}
return 0;
}

浙公网安备 33010602011771号