51nod1026 矩阵中不重复的元素 V2
$n \leq 500000,m \leq 500000$的矩阵,第一行第一列是$a^b,2 \leq a,b \leq 500000$,如果一个数是$i^j$那他右边是$i^{j+1}$,下面是${i+1}^{j}$,问这个矩阵里有多少不同的数字。
把数字化成“基”来统筹统计一些重复情况。意思就是:$a=\prod_{i=1}^{k}p_i^{b_i}$,其中$gcd(b_1,b_2,...,b_k)=1$,那么这些$a$就可以当基,他的若干次幂在比他小的行中一定不会出现,而他的平方,三次方,这些行可能会跟他有部分重复。因此这些行单独拿出来考虑。可以看一下次数:
$a^{1*1} \ \ a^{1*2} \ \ a^{1*3}...$
$a^{2*1} \ \ a^{2*2} \ \ a^{2*3}...$
$a^{3*1} \ \ a^{3*2} \ \ a^{3*3}...$
如此,只需要在这样的矩形里的一段连续行中去重就可以了。一次考虑一个记,元素总数是$log_an*m$的,但总的元素总数仍是$n*m$的。
可以观察到,随着基变大,这个抽象出来的矩形的连续行(叫$[L,R]$)的$L$和$R$都会变小。而这个矩形的数字范围只有$mlogn$,可以开个桶来算每次多出或损失的行。总复杂度变成这个矩形的元素总数$mlogn$。
V3暂时不会QAQ是用容斥的观点进行搜索+剪枝的,希望能回来填坑。
//#include<iostream>
#include<cstring>
#include<cstdio>
//#include<time.h>
//#include<complex>
//#include<set>
#include<queue>
//#include<vector>
#include<algorithm>
#include<stdlib.h>
using namespace std; #define LL long long
int qread()
{
char c; int s=,f=; while ((c=getchar())<'' || c>'') (c=='-') && (f=-);
do s=s*+c-''; while ((c=getchar())>='' && c<=''); return s*f;
} //Pay attention to '-' , LL and double of qread!!!! int n,m,a,b;
#define maxn 1000011
#define maxm 10000011 //int prime[maxn],lp,xx[maxn]; bool notprime[maxn];
//void makeprime(int n)
//{
// lp=0;
// for (int i=2;i<=n;i++)
// {
// if (!notprime[i]) {prime[++lp]=i; xx[i]=i;}
// for (int tmp,j=1;j<=lp && 1ll*i*prime[j]<=n;j++)
// {
// notprime[tmp=i*prime[j]]=1; xx[tmp]=prime[j];
// if (!(i%prime[j])) break;
// }
// }
//} int cnt[maxm]; bool vis[maxn];
int main()
{
m=qread(); n=qread(); a=qread(); b=qread(); int N=a+n-,M=b+m-;
// makeprime(a+n); int L=,R=; while ((<<L)<a) vis[<<L]=,L++; while ((<<R)>N) R--;
// cout<<L<<' '<<R<<endl;
for (int i=L;i<=R;i++) vis[<<i]=;
LL ans=; int now=;
for (int j=L,tmp;j<=R;j++)
for (int k=b;k<=M;k++)
{
if (cnt[tmp=j*k]==) now++;
cnt[tmp]++;
}
ans+=now;
for (int i=;i<=N;i++) if (!vis[i])
{
int nl=,nr=; LL tmp=;
for (;tmp<a;tmp*=i,nl++) vis[tmp]=;
nr=nl; for (;tmp<=N;tmp*=i,nr++) vis[tmp]=; nr--;
// cout<<nl<<' '<<nr<<endl;
for (int j=L-;j>=nl;j--)
for (int k=b;k<=M;k++)
{
if (cnt[tmp=j*k]==) now++;
cnt[tmp]++;
}
L=nl;
for (int j=R;j>nr;j--)
for (int k=b;k<=M;k++)
{
cnt[tmp=j*k]--;
if (cnt[tmp]==) now--;
}
R=nr;
ans+=now;
}
printf("%lld\n",ans);
return ;
}
51nod1026 矩阵中不重复的元素 V2的更多相关文章
- 1007 正整数分组 1010 只包含因子2 3 5的数 1014 X^2 Mod P 1024 矩阵中不重复的元素 1031 骨牌覆盖
1007 正整数分组 将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的. Input 第1行:一个 ...
- 51nod 1024 矩阵中不重复的元素
1024 矩阵中不重复的元素 题目来源: Project Euler 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 一个m*n的矩阵. 该矩阵的 ...
- [51NOD1024] 矩阵中不重复的元素(数学,精度)
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1024 因为n和m都到100了,所以直接快速幂硬算一定会爆炸,考 ...
- 51Nod 1024 矩阵中不重复的元素 | 技巧 数学
first try: set<LL> sset; int main() { LL m,n,a,b; while(~scanf("%lld%lld%lld%lld",&a ...
- Java基础知识强化之集合框架笔记27:ArrayList集合练习之去除ArrayList集合中的重复字符串元素
1. 去除ArrayList集合中的重复字符串元素(字符串内容相同) 分析: (1)创建集合对象 (2)添加多个字符串元素(包含重复的) (3)创建新的集合 (4)遍历旧集合,获取得到每一个元素 (5 ...
- linq 根据指定条件返回集合中不重复的元素
原理:先查询出数据,根据指定值分组,然后取第一条映射 1.第一种方法 string sql = string.Format("select*from PoliceLogistcs); db. ...
- c编程:求出4×4矩阵中最大和最小元素值及其所在行下标和列下标,求出两条主对角线元素之和。
//求出4×4矩阵中最大和最小元素值及其所在行下标和列下标,求出两条主对角线元素之和 #include <stdio.h> int main() { int sum=0; int max, ...
- 有序矩阵中第k小元素
有序矩阵中第k小元素 题目: 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素. 请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素. 看到有序就会想 ...
- javascript 返回数组中不重复的元素
这是实现结构伪类type-of-type的部分代码: <script type="text/javascript"> var ret= ["span" ...
随机推荐
- 微信程序开发系列教程(三)使用微信API给微信用户发文本消息
这个系列的第二篇教程,介绍的实际是被动方式给微信用户发文本消息,即微信用户关注您的公众号时,微信平台将这个关注事件通过一个HTTP post发送到您的微信消息服务器上.您对这个post请求做了应答(格 ...
- 立个单调栈flag
http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=687&pid=1002
- python自动化基础问题解析
(1)自动化代码中用到的设计模式: po模式(page object): 1.PO提供了一种业务流程与页面元素操作分离的模式,这使得测试代码变得更加清晰. 2.页面对象与用例分离,使得我们更好的复 ...
- Java第十二次作业:什么是一维数组?什么是对象数组?吃金币游戏2.0版 新增炸弹功能 新增游戏倒计时功能 新增胜利失败检测功能 使用如鹏游戏引擎制作窗体 一维数组设置金币
什么是数组? 数组的定义:是用统一的名字代表这批数据,用序号来区分各个数据.数组是无序的数据元素按有序的下标组成的集合,分配固定空间大小的一种容器. 如何理解:其实就是一个同时放很多数据的变量. a= ...
- Python学习笔记3(字典)
创建字典 dict函数 字典的格式化字符串 字典方法 clear copy fromkeys 序列是一个按照一定顺序将值进行组织的数据结构形式,可以通过索引对其进行征引.另外还有一种数据结构是通过名字 ...
- 【分块】[HNOI2010]弹飞绵羊&分块大法祭
分块(似乎还有一种动态树(LCT)做法) 第一次学习分块,似乎有点小激动 这是黄学长的分块入门博客「分块」数列分块入门1 – 9 by hzwer 题目描述 某天,Lostmonkey发明了一种超级弹 ...
- 【OS_Linux】Linux中虚拟机的三种上网方式——桥接、NAT、Host-only
1.桥接 桥接方便做实验,配置ip方便.可以和局域网中的其他机器进行通信,也可以和公网进行通信.缺点是会占用主机所在局域网的一个ip. 2. NAT NAT模式下虚拟机可以和主机进行通信,可以上网,而 ...
- 文件操作-dd
Linux dd命令 用于读取.转换并输出数据. dd可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件.设备或标准输出. 参数说明: if=文件名: 输入文件名,缺省为标准输入.即 ...
- 搭建pip源
1.安装pip软件 yum -y install python-pippip install --upgrade pippip install pip2pi 2.安装apacheyum -y inst ...
- redis 散列学习要点记录
散列类型键值也是种字典结构,存储了字段和字段值的映射,字段值只能是字符串,不可以是其他类型(redis数据类型都不可嵌套使用其他类型),散列类型键可以有2的32次方减1个字段 散列的命令组 hset ...