818E - Card Game Again

题意

给出一个数列,选择连续的一段使得这些数字的乘积是 k 的倍数,问合法的方案数。

分析

尺取法。设 num 为连续的数的乘积,只要对于 k 的每个素因子,num 相应的素因子的个数大于等于它。那么不仅这个数,后面乘上任意数都是 k 的倍数。这时候就不用移动 r 指针了,移动 l 指针,即不断的去掉前面的数。

计算时可以用 map 存下素因子及其个数。

code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
const int MAXN = 3e4 + 2e3;
const int INF = 2e9 + 1;
int is[MAXN];
vector<int> prime;
void init() {
for(int i = 2; i < MAXN; i++) {
if(!is[i]) {
prime.push_back(i);
for(ll j = 1LL * i * i; j < MAXN; j += i) {
is[j] = 1;
}
}
}
}
int a[N];
struct nd {
int x, cnt;
};
vector<nd> getFactor(int x) {
vector<nd> v;
for(int i = 0; 1LL * prime[i] * prime[i] <= x; i++) {
int c = 0;
while(x % prime[i] == 0) {
x /= prime[i];
c++;
}
if(c) v.push_back(nd{prime[i], c});
}
if(x > 1) v.push_back(nd{x, 1});
return v;
}
map<int, vector<nd> > mp;
int C[MAXN];
set<int> st;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
init();
int n, k;
cin >> n >> k;
for(int i = 0; i < n; i++) {
cin >> a[i];
}
int l = 0, r = 0;
vector<nd> K = getFactor(k);
ll ans = 0;
int state = 1;
while(l < n && r < n) {
vector<nd> X;
if(state) {
if(!mp.count(a[r])) mp[a[r]] = getFactor(a[r]);
X = mp[a[r]];
for(int i = 0; i < X.size(); i++) {
if(X[i].x > MAXN) st.insert(X[i].x);
else C[X[i].x] += X[i].cnt;
}
} else {
if(!mp.count(a[l])) mp[a[l]] = getFactor(a[l]);
X = mp[a[l]];
for(int i = 0; i < X.size(); i++) {
if(X[i].x > MAXN) st.erase(X[i].x);
else C[X[i].x] -= X[i].cnt;
}
l++;
}
int flg = 0;
for(int i = 0; i < K.size(); i++) {
if(K[i].x > MAXN) { if(!st.count(K[i].x)) { flg = 1; break; } }
else if(K[i].cnt > C[K[i].x]) { flg = 1; break; }
}
if(flg) {
r++;
state = 1;
} else {
ans += n - r;
if(l == r) { r++; l++; state = 1; memset(C, 0, sizeof C); st.clear(); }
else state = 0;
}
}
cout << ans << endl;
return 0;
}

818E - Card Game Again(尺取法)的更多相关文章

  1. hdu 6205 card card card 尺取法

    card card card Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  2. HDU - 6205 card card card (尺取法)

    题意:有n堆牌,ai表示每堆牌的牌数,bi表示每堆牌的penaltyvalue,操作开始前,可以重复进行将第一堆牌挪到最后一堆这一操作.然后,对于挪完后的牌,从第一堆开始,依次取.对于每一堆牌,首先将 ...

  3. FZU-2216 The Longest Straight(尺取法)

     Problem 2216 The Longest Straight Accept: 523    Submit: 1663Time Limit: 1000 mSec    Memory Limit ...

  4. 5806 NanoApe Loves Sequence Ⅱ(尺取法)

    传送门 NanoApe Loves Sequence Ⅱ Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/131072 K ...

  5. POJ3061 尺取法

    题目大意:从给定序列里找出区间和大于等于S的最小区间的长度. 前阵子在zzuli OJ上见过类似的题,还好当时补题了.尺取法O(n) 的复杂度过掉的.尺取法:从头遍历,如果不满足条件,则将尺子尾 部增 ...

  6. POJ 2739 Sum of Consecutive Prime Numbers(尺取法)

    题目链接: 传送门 Sum of Consecutive Prime Numbers Time Limit: 1000MS     Memory Limit: 65536K Description S ...

  7. CF 701C They Are Everywhere(尺取法)

    题目链接: 传送门 They Are Everywhere time limit per test:2 second     memory limit per test:256 megabytes D ...

  8. nyoj133_子序列_离散化_尺取法

    子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:5   描述 给定一个序列,请你求出该序列的一个连续的子序列,使原串中出现的所有元素皆在该子序列中出现过至少1次. 如2 8 ...

  9. Codeforces 676C Vasya and String(尺取法)

    题目大概说给一个由a和b组成的字符串,最多能改变其中的k个字符,问通过改变能得到的最长连续且相同的字符串是多长. 用尺取法,改变成a和改变成b分别做一次:双指针i和j,j不停++,然后如果遇到需要改变 ...

随机推荐

  1. 《Cracking the Coding Interview》——第4章:树和图——题目4

    2014-03-19 03:40 题目:给定一棵二叉树,把每一层的节点串成一个链表,最终返回一个链表数组. 解法:前序遍历,遍历的同时向各个链表里添加节点.水平遍历好像还不如前序遍历来得方便. 代码: ...

  2. CodeIgniter学习笔记五:分页,文件上传,session,验证码

    一.分页 示例代码: //装载类文件 $this -> load -> library('pagination'); $controller = $this->router-> ...

  3. Python 3基础教程8--if else、if elif else

    本文介绍if else语句,不多说,直接看例子. if elif else语句

  4. js 全局变量和局部变量

    Javascript在执行前会对整个脚本文件的声明部分做完整分析(包括局部变量),但是不能对变量定义做提前解析 1.作用域和作用域链 2.变量声明提前

  5. SDK接入注意点

    1. 新建的android项目,要把MainActivity.java里生成的东西全部删去,最好只留个onCreate入口方法,不然会产生什么“hello world”,会把自己写的View内的东西覆 ...

  6. Unity插件

    1.2D Toolkit 如果过去你一直从事3D游戏开发,最近想转做2D游戏,最好尝试一下2D Toolkit.2D Toolkit是一款2D开发组件,它具有很强的灵活性和适应性,能够让开发者在Uni ...

  7. 分享6个网址二维码API接口

    1.http://pan.baidu.com/share/qrcode?w=150&h=150&url=http://www.54admin.net 2.http://b.bshare ...

  8. leetcode 214. 最短回文串 解题报告

    给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串.找到并返回可以用这种方式转换的最短回文串. 示例 1: 输入: "aacecaaa" 输出: "aaa ...

  9. 重复造轮子系列--字符串处理(C语言)

    这些字符代码是以前写的,源于很久很久以前的一个VC++项目,在当时的部门编程比赛里因为用了项目代码的xsplit函数,万万没想到,那个做了几年的项目里面居然有坑..xsplit函数居然不能split连 ...

  10. [洛谷P3805]【模板】manacher算法

    题目大意:给你一个字符串,求出它的最长回文字段 题解:$manacher$算法 卡点:$p$数组未开两倍空间 C++ Code: #include <cstdio> #include &l ...