题意:给定n*m的格子,每个格子有不同的种类,q次操作,每次操作使[x1,y1]到[x2,y2]的格子除了k类型的以外都删除,最后单次询问所有格子被删了几个

官方题解提到了两种有意思的做法,随机和二进制分组

目前我写了随机的做法,简单粗暴好懂

(upd.劳资总算把二进制分组的给做出来了!

给每种类型打个随机权值,操作覆盖到的区间都加上这个权值

最后查询的时候只需这道这个点的值是不是该类型的权值的倍数就行了

就这么简单

实现上只需套路作差取前缀和就能得到单点的值,总复杂度\(O(n)\)

(WA了几发忘记递推前缀了...)

另外提一下二进制分组的思路

对于每个操作的整体而不考虑细节来说,

普通的是更新\(O(1)\),针对特定的一组

要比较的是\(O(n)\),对应于除了该类型外的其他所有组

那么二进制分组就把各个类型按二进制归类,如果某一位是1就把它归类到某一组,总共\(log_2n\)组

要比较是否有别的数打到这个格子上,那么必然在二进制的某一位上存在差异

因此可以更新\(O(logn)\)

查询也是\(O(logn)\)

具体说明:

搞个特例,种类只有0和1,那么对于1而言0的个数只要大于0就不可以,0而言只要1的个数大于0则不可以

扩展到1e6种,把各个类型分拆成二进制后就是20个0和1的组合,分别维护40个前缀和就可以了

注意第二种方法在实现上不要用vector,不然会各种姿势爆内存

用数组记得保证不越界

#include<bits/stdc++.h>
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define rrep(i,j,k) for(int i=j;i>=k;i--)
#define erep(i,u) for(int i=head[u];~i;i=nxt[i])
#define print(a) printf("%lld",(ll)(a))
#define printbk(a) printf("%lld ",(ll)(a))
#define println(a) printf("%lld\n",(ll)(a))
using namespace std;
const int MAXN = 1e5+11;
const int MAXM = 2e6+11;
const int MOD = 1e9+7;
typedef long long ll;
unsigned int xjb=2333333;
int Rand(){
return (xjb=xjb*12345+23333)%MOD+1;
}
ll read(){
ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
vector<vector<ll> > G,type,pre;
vector<ll> vec;
int main(){
int n,m,op;
while(cin>>n>>m>>op){
G.clear();type.clear();vec.clear();pre.clear();
G.resize(n+3);type.resize(n+3);pre.resize(n+3);
rep(i,0,n+2){
G[i].resize(m+3);
type[i].resize(m+3);
pre[i].resize(m+3);
}
rep(i,1,n) rep(j,1,m) type[i][j]=read();
vec.push_back(Rand());
rep(i,1,n)rep(j,1,m) vec.push_back(Rand());
rep(i,1,op){
int x_1=read();
int y_1=read();
int x_2=read();
int y_2=read();
int k=read();
G[x_1][y_1]+=vec[k];
G[x_2+1][y_1]-=vec[k];
G[x_1][y_2+1]-=vec[k];
G[x_2+1][y_2+1]+=vec[k];
}
ll val=0,cnt=0;
rep(i,1,n) rep(j,1,m){
pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+G[i][j];
if(pre[i][j]%vec[type[i][j]]!=0) cnt++;
}
println(cnt);
}
return 0;
}
#include<bits/stdc++.h>
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define rrep(i,j,k) for(int i=j;i>=k;i--)
#define erep(i,u) for(int i=head[u];~i;i=nxt[i])
#define print(a) printf("%lld",(ll)(a))
#define printbk(a) printf("%lld ",(ll)(a))
#define println(a) printf("%lld\n",(ll)(a))
using namespace std;
const int MAXN = 1e6+11;
const int MAXM = 2e6+11;
const int MOD = 1e9+7;
typedef long long ll;
ll read(){
ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int G[21][2][MAXN],type[MAXN],sum[2][MAXN];
bool gg[MAXN];
int n,m,op;
int id(int r,int c){
if(r<1||c<1) return 0;
return (r-1)*m+c;
}
int main(){
while(cin>>n>>m>>op){
memset(G,0,sizeof G);
memset(sum,0,sizeof sum);
memset(gg,0,sizeof gg);
rep(i,1,n) rep(j,1,m) type[id(i,j)]=read();
rep(i,1,op){
int x_1=read();
int y_1=read();
int x_2=read();
int y_2=read();
int k=read();
rep(j,0,20){
bool pos=k>>j&1;
G[j][pos][id(x_1,y_1)]++;
if(x_2<n)G[j][pos][id(x_2+1,y_1)]--; //limited
if(y_2<m)G[j][pos][id(x_1,y_2+1)]--;
if(x_2<n&&y_2<m)G[j][pos][id(x_2+1,y_2+1)]++;
}
}
int cnt=0;
rep(k,0,20) rep(i,1,n) rep(j,1,m){
sum[0][id(i,j)]=sum[0][id(i-1,j)]+sum[0][id(i,j-1)]-sum[0][id(i-1,j-1)]+G[k][0][id(i,j)];
sum[1][id(i,j)]=sum[1][id(i-1,j)]+sum[1][id(i,j-1)]-sum[1][id(i-1,j-1)]+G[k][1][id(i,j)];
bool pos=type[id(i,j)]>>k&1;
if(sum[!pos][id(i,j)]>0) gg[id(i,j)]=1;
}
rep(i,1,n) rep(j,1,m) cnt+=gg[id(i,j)];
println(cnt);
}
return 0;
}

2018牛客多校2 - J farm 随机乱搞/二进制分组的更多相关文章

  1. 2018牛客多校1 - J Different Integers 莫队/主席树签到

    题意:给出n<5e4,a[1...n],单次1e5总次1e6次查询除去区间(L,R)的数的个数 开场5分钟:莫队是不可能莫队的,这道题是不可能莫队的 最后1小时:真香 具体操作没啥特别的,注意一 ...

  2. 2018牛客多校6 - I Team Rocket KD树维护空间

    题意:给出n条铁路区间\([L,R]\),共有m个boom依时间顺序放置在\(k_i\)中,区间与\(k_i\)有交集的都被炸掉 求每次炸掉的铁路个数和最后输出所有id被炸的时间点 炸弹能炸到的区间满 ...

  3. 2018牛客多校第四场 J.Hash Function

    题意: 给出一个已知的哈希表.求字典序最小的插入序列,哈希表不合法则输出-1. 题解: 对于哈希表的每一个不为-1的数,假如他的位置是t,令s = a[t]%n.则这个数可以被插入当且仅当第s ~ t ...

  4. 2018牛客多校第五场 E.room

    题意: 一共有n个宿舍,每个宿舍有4个人.给出第一年的人员分布和第二年的人员分布,问至少有多少人需要移动. 题解: 对于第一年的每个宿舍,向今年的每种组合连边.流量为1,费用为(4 - 组合中已在该宿 ...

  5. 2018牛客多校第一场 B.Symmetric Matrix

    题意: 构造一个n*n的矩阵,使得Ai,i = 0,Ai,j = Aj,i,Ai,1+Ai,2+...+Ai,n = 2.求种类数. 题解: 把构造的矩阵当成邻接矩阵考虑. 那么所有点的度数都为2,且 ...

  6. 2018牛客多校第一场 A.Monotonic Matrix

    题意: 给一个n*m的矩阵赋值(0,1,2).使得每个数都不小于它左面和上面的数. 题解: 构建0和1的轮廓线.对于单独的轮廓线,共需要往上走n步,往右走m步.有C(n+m,n)种方式. 两个轮廓线的 ...

  7. 2018牛客多校第一场 D.Two Graphs

    题意: n个点,m1条边的图E1,n个点,m2条边的图E2.求图E2有多少子图跟图E1同构. 题解: 用STL的全排列函数next_permutation()枚举映射.对于每一种映射枚举每一条边判断合 ...

  8. 2018牛客多校第九场E(动态规划,思维,取模)

    #include<bits/stdc++.h>using namespace std;const long long mod=1000000007,inv=570000004;long l ...

  9. 2018牛客多校第一场 E-Removal【dp】

    题目链接:戳这里 转自:戳这里 题意:长度为n的序列,删掉m个数字后有多少种不同的序列.n<=10^5,m<=10. 题解:dp[i][j]表示加入第i个数字后,总共删掉j个数字时,有多少 ...

随机推荐

  1. code1225 搭积木

    题目分析:将当前层定义为第h层,共用了n块积木,本层积木数为m,f(h,n,m) 那么可以扩展数两种状态:f(h-1,n-m,m-1),f(h-1,n-m,m+1) 直接搜索可能的数据达到h^m,超时 ...

  2. block functions区块函数插件的定义与使用

    在插件目录plugins里新建文件 block.插件名.php文件(如 block.插件名.php) 例:block.test2.php <?php function smarty_block_ ...

  3. python 输入输出,file, os模块

    Python 输入和输出 输出格式美化 Python两种输出值的方式: 表达式语句和 print() 函数. 第三种方式是使用文件对象的 write() 方法,标准输出文件可以用 sys.stdout ...

  4. Qt之生成pdf(转)

    Qt中如何让图片.文本.HTML或者其他形式的内容生成pdf呢?主要利用QPrinter来实现,QPrinter不止可以操作打印机来打印纸张文件,并且可以将文件保存至磁盘,存储为pdf格式的文件.   ...

  5. Qt的翻译文件QTranslator不能使用问题总结(原)

    笔者今天在自己工程中使用翻译文件,发现没有起作用,反复查找,发现是用宏定义了命名空间,生成.ts文件时,不会加上命名空间,所以生成的.qm文件在实际使用时,会无法找到对应的语句. 如果将宏定义的命名空 ...

  6. 【转载】mysql中timestamp,datetime,int类型的区别与优劣

    转载来自souldak,微博:@evagle以下内容整合筛选自互联网: int1. 占用4个字节2. 建立索引之后,查询速度快3. 条件范围搜索可以使用使用between4. 不能使用mysql提供的 ...

  7. css3的那些高级选择器二

    在上个星期我介绍了css3的属性选择器,伪类选择器和结构伪类选择器,今天楼主继续把其它的css3选择器说完. 在css3中,共有11中UI状态伪类选择器,分别是E:hover,E:active,E:f ...

  8. SPARK_sql加载,hive以及jdbc使用

    sql加载 格式  或者下面这种直接json加载 或者下面这种spark的text加载 以及rdd的加载 上述记得配置文件加入.mastrt("local")或者spark://m ...

  9. phpize命令在安装AMQP插件是报错phpize:Cannot find autoconf. Please check your autoconf installation and the $PHP_AUTOCONF envir的解决方法

    phpize命令在安装AMQP插件是报错phpize:Cannot find autoconf. Please check your autoconf installation and the $PH ...

  10. 底部导航栏使用BottomNavigationBar

    1.github地址 https://github.com/zhouxu88/BottomNavigationBar 2.基本使用 2,1添加依赖 implementation 'com.ashokv ...