Codeforces Round #305 (Div. 2)
C. Mike and Frog
题意:有一只青蛙和一朵花,分别高度为h1、h2,每浇一次水,h1=(x1*h1+y1)mod m,h2=(x2*h2+y2)mod m。求最少浇多少次后h1=a1,h2=a2?
思路:先遍历m次找到第一次达到a1、a2的次数(若无,则为-1);再找到各自的循环节长度,然后枚举m次循环,判断能否符合题意。注意,可能在y2=0的时候,导致a2只出现一次,后面由于出现0而使得0对任意数取模都为0,则应当特别处理。
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int m, a1, x1, y1, a2, x2, y2;
long long h1, h2;
scanf("%d", &m);
scanf("%I64d%d%d%d", &h1, &a1, &x1, &y1);
scanf("%I64d%d%d%d", &h2, &a2, &x2, &y2);
int len1=-, len2=-, st1=-, st2=-;
for (int i = ; i <= * m; i++)
{
h1 = (x1*h1 + y1) % m;
h2 = (x2*h2 + y2) % m;
if (h1 == a1)
{
if (st1 == -) st1 = i;
else if (len1 == -) len1 = i - st1;
}
if (h2 == a2)
{
if (st2 == -) st2 = i;
else if (len2 == -) len2 = i - st2;
}
if (len1 != - && len2 != -) break;
}
if (st1 == - || st2 == -||(len1==-&&len2==-&&st1!=st2)) printf("-1\n");
else
{
bool flag = false;
for (int i = ; i <= m; i++)
{
if (len1 > && len2 > )
{
if ((1ll * st1 + 1ll * i * len1) >= st2 && (1ll * st1 + 1ll * i * len1 - st2) % len2 == )
{
printf("%I64d\n", 1ll * st1 + 1ll * i * len1);
flag = true;
break;
}
}
else if (len1 > )
{
if ((1ll * st1 + 1ll * i * len1) == st2)
{
printf("%I64d\n", 1ll * st1 + 1ll * i * len1);
flag = true;
break;
}
}
else break;
}
if (!flag)
{
for (int i = ; i <= m; i++)
{
if (len1 > && len2 > )
{
if ((1ll * st2 + 1ll * i * len2) >= st1 && (1ll * st2 + 1ll * i * len2 - st1) % len1 == )
{
printf("%I64d\n", 1ll * st2 + 1ll * i * len2);
flag = true;
break;
}
}
else if (len2 > )
{
if ((1ll * st2 + 1ll * i * len2) == st1)
{
printf("%I64d\n", 1ll * st2 + 1ll * i * len2);
flag = true;
break;
}
}
else break;
}
}
if (!flag) printf("-1\n");
} return ;
}
/*
999983
408725 408721
1 1
378562 294895
984270 0
499981500166
*/
/*
16
1 0
2 0
1 2
2 0
-1
*/
D. Mike and Feet
题意:有n只熊,每只熊有一个身高,他们站成一列。问区间长度为i时,所有区间最小值的最大值是多少?
思路:用单调栈分别求出每只熊其向左、向右最远的大于等于它身高的熊的位置。设为Li、Ri,则在区间[Li,Ri]内,熊i的身高是最低的,显然ans[Ri-Li+1]=max(ans[Ri-Li+1],h[i]),显然的,在该区间内,长度为min(i-Li+1,Ri-i+1)~Ri-Li+1的区间长度的最小值就为h[i],而对于该区间内区间长度小于min(i-Li+1,Ri-i+1)的最小值,自然可由那些位置的熊的Lj、Rj来确定。而我们此处设置最大范围为该最小值h[i],那么之后我们可以用大区间的值来更新小区间的值。另做证明:如果len1>len2,但是ans[len1]>ans[len2],说明大区间最小值的最大值比小区间的最小值的最大值还大,说明存在某一个长度为len1的大区间,其最小值为v1,那么显然在该大区间内部去一个长度为len2的小区间,则该小区间内最小值至少大于等于v1。故可用大区间的值来更新小区间的值。
#include<iostream>
#include<stack>
#include<algorithm>
#include<cstdio>
using namespace std;
const int maxn = ;
int v[maxn];
int L_index[maxn];
int R_index[maxn];
int ans[maxn];
int main()
{
int n;
scanf("%d", &n);
for (int i = ; i <= n; i++) scanf("%d", v + i);
stack<int>stkL,stkR;
for (int i = ; i <= n; i++)
{
while (!stkL.empty() && v[i] <= v[stkL.top()]) stkL.pop();
if (stkL.empty()) L_index[i] = ;
else L_index[i] = stkL.top() + ;
stkL.push(i);
}
for (int i = n; i>=; --i)
{
while (!stkR.empty() && v[i] <= v[stkR.top()]) stkR.pop();
if (stkR.empty()) R_index[i] = n;
else R_index[i] = stkR.top() - ;
stkR.push(i);
}
for (int i = ; i <= n; i++)
{
int len = R_index[i] - L_index[i] + ;
ans[len] = max(ans[len], v[i]);
}
for (int i = n-; i >= ; --i)
{
ans[i] = max(ans[i], ans[i + ]);
}
for (int i = ; i <= n; i++)
{
if (i > ) printf(" ");
printf("%d", ans[i]);
}
printf("\n"); return ;
}
E. Mike and Foam
题意:有n杯啤酒,每杯啤酒的泡沫含量为ai。现在有一个空架子,q次询问,每次询问一杯啤酒的编号,如果其在架子上,则将其拿下,否则将其放上。并在每次询问后求架子上泡米含量互质的啤酒的对数。
思路:先求出含量ai其所有的质因子。然后求所有质因子的并集(容斥原理),得到与ai不互质的个数,然后架子上的啤酒个数减去ai就是与ai互质的对数。并且我们每次询问可以累积这个对数,这样每次无论是放上还是取下啤酒,都只需找到与进行操作的啤酒的互质的个数即可。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int maxv = ;
const int maxn = ;
int v[maxn];
bool isOnShelf[maxn];
vector<int>p[maxv];//存放2~maxv各个数的质因子
int n, q;
int sets[maxv];//存放各个质因子及其乘积的个数
int preCount;//之前架子上的及啤酒个数
long long pre;//之前架子上互质的对数
void Init()
{
for (int i = ; i < maxv; i++)
{
if (p[i].empty())
{
for (int j = i; j < maxv; j += i)
{
p[j].push_back(i);
}
}
}
} void removeBeer(int x)
{
int len = p[x].size();
int tot = ( << len) - ;
int tans = ;
//二进制枚举质因子个数,进行容斥,找到已有数的集合中与x不互质的个数(也就是含有至少一个相同质因子的个数,p1,p2,...,p_len的并集)
for (int i = ; i <= tot; i++)
{
//得到当前状态下各质因子的乘积及其个数
int cur = ,nums=;
for (int j = ; j < len; j++)
{
if (( << j)&i)
{
cur *= p[x][j], nums++;
}
}
//在cur的集合中减去一个数(即x自身的若干质因子的乘积),因为要把x从当前数的集合减去
sets[cur]--;
//奇加偶减
if (nums % ) tans += sets[cur];
else tans -= sets[cur];
}
preCount--;//减去x自身
pre -= (preCount - tans);
}
void addBeer(int x)
{
int len = p[x].size();
int tot = ( << len) - ;
int tans = ;
//二进制枚举质因子个数,进行容斥,找到已有数的集合中与x不互质的个数(也就是含有至少一个相同质因子的个数,p1,p2,...,p_len的并集)
for (int i = ; i <= tot; i++)
{
//得到当前状态下各质因子的乘积及其个数
int cur = , nums = ;
for (int j = ; j < len; j++)
{
if (( << j)&i)
{
cur *= p[x][j], nums++;
}
}
//奇加偶减
if (nums % ) tans += sets[cur];
else tans -= sets[cur];
//在cur的集合中加去一个数(即x自身的若干质因子的乘积),因为要把x放入当前数的集合
sets[cur]++;
}
pre += (preCount - tans);
preCount++;//加上x自身
}
int main()
{
Init();
scanf("%d%d", &n, &q);
for (int i = ; i <= n; i++) scanf("%d", v + i);
while (q--)
{
int index;
scanf("%d", &index);
if (isOnShelf[index])
{
removeBeer(v[index]);
printf("%I64d\n", pre);
isOnShelf[index] = false;
}
else
{
addBeer(v[index]);
printf("%I64d\n", pre);
isOnShelf[index] = true;
}
}
return ;
}
Codeforces Round #305 (Div. 2)的更多相关文章
- set+线段树 Codeforces Round #305 (Div. 2) D. Mike and Feet
题目传送门 /* 题意:对于长度为x的子序列,每个序列存放为最小值,输出长度为x的子序列的最大值 set+线段树:线段树每个结点存放长度为rt的最大值,更新:先升序排序,逐个添加到set中 查找左右相 ...
- 数论/暴力 Codeforces Round #305 (Div. 2) C. Mike and Frog
题目传送门 /* 数论/暴力:找出第一次到a1,a2的次数,再找到完整周期p1,p2,然后以2*m为范围 t1,t2为各自起点开始“赛跑”,谁落后谁加一个周期,等到t1 == t2结束 详细解释:ht ...
- 暴力 Codeforces Round #305 (Div. 2) B. Mike and Fun
题目传送门 /* 暴力:每次更新该行的num[],然后暴力找出最优解就可以了:) */ #include <cstdio> #include <cstring> #includ ...
- 字符串处理 Codeforces Round #305 (Div. 2) A. Mike and Fax
题目传送门 /* 字符串处理:回文串是串联的,一个一个判断 */ #include <cstdio> #include <cstring> #include <iostr ...
- Codeforces Round #305 (Div. 2) B. Mike and Fun 暴力
B. Mike and Fun Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/548/pro ...
- Codeforces Round# 305 (Div 1)
[Codeforces 547A] #include <bits/stdc++.h> #define maxn 1000010 using namespace std; typedef l ...
- Codeforces Round #305 (Div. 2) A. Mike and Fax 暴力回文串
A. Mike and Fax Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/548/pro ...
- Codeforces Round #305 (Div. 1) B. Mike and Feet 单调栈
B. Mike and Feet Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/547/pro ...
- Codeforces Round #305 (Div. 1) A. Mike and Frog 暴力
A. Mike and Frog Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/547/pr ...
- 「日常训练」Mike and Feet(Codeforces Round #305 Div. 2 D)
题意 (Codeforces 548D) 对一个有$n$个数的数列,我们要求其连续$x(1\le x\le n)$(对于每个$x$,这样的连续group有若干个)的最小数的最大值. 分析 这是一道用了 ...
随机推荐
- SAM I AM UVA - 11419 最小点集覆盖 要输出具体覆盖的行和列。
/** 题目:SAM I AM UVA - 11419 链接:https://vjudge.net/problem/UVA-11419 题意:给定n*n的矩阵,'X'表示障碍物,'.'表示空格;你有一 ...
- Linux网络实时监控配置
Linux监控邮件发送配置 网络状态监控 网络状态:netstat 各个状态的总计,详情:以及重点端口的详细连接情况(22,25,80,3306,8080),打印客户端连接数最多的ip. 邮件报告当前 ...
- 【BZOJ】3401: [Usaco2009 Mar]Look Up 仰望(单调栈)
http://www.lydsy.com/JudgeOnline/problem.php?id=3401 还能更裸一些吗.. 维护一个递减的单调栈 #include <cstdio> #i ...
- 一个事半功倍的c#方法 动态注册按钮事件
前几天在网上看见一个制作计算器的c#程序,其中有一个动态注册按钮事件,觉的很有用.于是实际操作了一哈, 确实比较好. 言归正传,下面就来讲讲怎样动态注册按钮事件. 首先,我们需要设置变量来获取点击一个 ...
- 【Google Earth】pro之视频录制
一.谷歌地球文件简介 谷歌地球能识别的文件分为:gpx.kml.kmz文件.谷歌地球的官方文件为kml和kmz,其中kmz是kml和图片.模型等数据的压缩文件,kml为数据信息文件,也可以分为航迹和字 ...
- python3----生成器generator(yield)
# 列表推导式a = [i for i in range(100) if not(i % 2) and (i % 3)]print(a)# 字典推导式b = {i: i % 2 == 0 for i ...
- 软件设计模式(Design pattern)(待续)
软件设计模式是在面向对象的系统设计过程中反复出现的问题解决方案. 设计模式通常描述了一组相互紧密作用的类与对象. 设计模式提供一种讨论软件设计的公共语言,使得熟练设计者的设计经验可以被初学者和其他设计 ...
- Sql Server 数据库用Transact-SQL语句创建链接服务器
1.在查询编辑器中,输入以下 Transact-SQL 命令以便链接到名为 SRVR002\ACCTG 的 SQL Server 实例: USE [master] GO EXEC master.dbo ...
- 《从零开始学Swift》学习笔记(Day 58)—— Swift编码规范之变量或常量声明规范
原创文章,欢迎转载.转载请注明:关东升的博客 声明是在声明变量.常量.属性.方法或函数和自定义类型时候需要遵守的规范. 首先变量或常量时每行声明变量或常量的数量推荐一行一个,因为这样以利于写注释.示例 ...
- hibernate中inverse作用
默认 inverse="false"即该元素指向的类负责维护该关系. 如: <hibernate-mapping> <class name="com.h ...