题目链接:https://ac.nowcoder.com/acm/contest/5674#question
A-Groundhog and 2-Power Representation
题意
- 求表达式的值
- 只有2 0 + ( ) 组成
- 2(0)表示2的0次
- 用python写非常方便
- 写个x(i)函数表示2的幂次,然后将字符串中的"2("字符替换成"x("
- 最后调用eval函数将字符串变成有效的表达式求值并返回结果
def x(i):
return 2**i
str = input()
str = str.replace("2(","x(")
print(eval(str))
E-Groundhog Chasing Death 题意
- 求
文章图片
mod 998244353的结果
- 唯一分解定理:任何数都可以表示成质因子幂次相乘的形式。
文章图片
,
文章图片
- gcd(n,m)=
文章图片
- 因为
文章图片
,所以设p是n,m共有的质因子,k1和k2是n,m对于p的幂次,则就是求解
文章图片
(p是n,m共有的质因子) - 优化一个for,找到k1*i和k2*j的零界点sh,sh=k1*i/k2,此时j在sh左边的时候,min总是取k1*i,由于此时的i不变,直接乘数量就好了;j在sh右边的时候,min总是取k2*j,由于j在变,不过就是对等差数列求和。
- 数规模会很大,取模太多又感觉很烦,其他人是通过欧拉降幂优化,我门就很莽,直接__int128冲,最后取模!!
#include
#define LL long long
#define sc(a) scanf("%d", &a)
#define sc2(a, b) scanf("%d%d", &a, &b)
#define sc3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define scl(a) scanf("%lld", &a)
#define scl2(a, b) scanf("%lld%lld", &a, &b)
#define ss(a) scanf("%s", a)
#define mem(a, b) memset(a, b, sizeof(a))
#define PII pair
#define ll __int128
using namespace std;
const ll mod = 998244353;
inline void print(__int128 x)
{
if (x < 0)
{
x = -x;
putchar('-');
}
if (x > 9)
print(x / 10);
putchar(x % 10 + '0');
}
template
inline void read(_Tp &x)
{
char ch;
bool flag = 0;
x = 0;
while (ch = getchar(), !isdigit(ch))
if (ch == '-')
flag = 1;
while (isdigit(ch))
x = x * 10 + ch - '0', ch = getchar();
if (flag)
x = -x;
}
inline ll POW(ll a, ll b)
{
ll ans = 1;
while (b)
{
if (b & 1)
ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans;
}
map num1;
//存放x质因子和需要幂的数ai
map num2;
//存放y质因子和需要幂的数bi
map ans;
//共同质因子和需要幂的数
int main()
{
ll a, b, c, d, x, y;
read(a);
read(b);
read(c);
read(d);
read(x);
read(y);
for (ll i = 2;
i * i <= x;
i++) //x质因子分解
if (x % i == 0)
{
int cnt = 0;
while (x % i == 0)
cnt++, x /= i;
num1[i] = cnt;
}
if (x != 1)
num1[x] = 1;
for (ll i = 2;
i * i <= y;
i++) //y质因子分解
if (y % i == 0)
{
int cnt = 0;
while (y % i == 0)
cnt++, y /= i;
num2[i] = cnt;
}
if (y != 1)
num2[y] = 1;
for (auto p : num1)
{
if (!num2[p.first])
continue;
ll pi = p.first, k1 = p.second, k2 = num2[pi];
for (ll i = a;
i <= b;
i++)
{
ll sh = k1 * i / k2;
//j从1到sh,min都是k1*i;
//j大于sh,min都是k2*j
if (sh < c)
ans[pi] += k1 * i * (d - c + 1);
else if (sh >= d)
ans[pi] += k2 * (c + d) * (d - c + 1) / 2;
//等差数列求和
else
ans[pi] += k1 * i * (d - sh) + k2 * (sh + c) * (sh - c + 1) / 2;
}
}
ll res = 1;
for (auto p : ans) //所有共同质因子幂次累乘
res = res * POW(p.first, p.second) % mod;
print(res % mod);
system("pause");
return 0;
}
F-Groundhog Looking Dowdy 题意
- 给定n天,每天生产ki件衣服,选择m件来自不同天的衣服,求最大价格和最小价格的最小差值
- 数据范围:1<=aij<=1e9,1<=n<=1e6,1<=m<=n,sum of clothes<=2e6,k>=1
- 尺取法。
- 首先结构体存衣服生产日期和价格,按照价格从小到大排序。
- l,r分别是左右端点,当区间内衣服不同生产日期数num没有超过m时,r++;
- 等于m时,更新左右端点价格差值的最小值 ,l++,直到num
#include
#define LL long long
#define sc(a) scanf("%d", &a)
#define sc2(a, b) scanf("%d%d", &a, &b)
#define sc3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define scl(a) scanf("%lld", &a)
#define scl2(a, b) scanf("%lld%lld", &a, &b)
#define ss(a) scanf("%s", a)
#define mem(a, b) memset(a, b, sizeof(a))
#define PII pair
using namespace std;
const double pi = acos(-1.0);
const int mod = 1e9 + 7;
const int maxn = 1e6+5;
const int inf = 0x3f3f3f3f;
struct node{
int val,id;
bool operator < (const node &a)const{
return val
由于数据给的弱,以下代码可以水过去,要不是敲得慢,差点拿一血QAQ
#include
#define LL long long
#define sc(a) scanf("%d", &a)
#define sc2(a, b) scanf("%d%d", &a, &b)
#define sc3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define scl(a) scanf("%lld", &a)
#define scl2(a, b) scanf("%lld%lld", &a, &b)
#define ss(a) scanf("%s", a)
#define mem(a, b) memset(a, b, sizeof(a))
#define PII pair
using namespace std;
const int maxn = 2e5+5;
const int inf = 0x3f3f3f3f;
int main(){
int n,m;
sc2(n,m);
vectorv;
while(n--){
int k,x,mii=inf;
sc(k);
while(k--){
sc(x);
mii=min(mii,x);
}
v.push_back(mii);
//每天取最便宜的
}
sort(v.begin(),v.end());
//从小到大排
cout<
I-The Crime-solving Plan of Groundhog 题意
- 给一个序列仅包含数字,让你将其打乱次序并组合成两部分,使这两部分组成的数字相乘得到的结果最小
- 不允许任何一部分组成的数字包含前导零
- 大数运算。 两位乘两位的数字一定比一位乘三位的数字大。证明过程如下:
- (10a+d)*(10b+c)=100ab+10ac+10bd+cd
- (100b+10c+d)*a=100ab+10ac+ad<(10a+d)*(10b+c)
- 组合成1位数乘n-1位数
- 1位数是除零外最小的
- n-1位数是第一位是除零最小,接着是从小到大加入
- 然后是模拟乘法运算。
#include
#define LL long long
#define sc(a) scanf("%d", &a)
#define sc2(a, b) scanf("%d%d", &a, &b)
#define sc3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define scl(a) scanf("%lld", &a)
#define scl2(a, b) scanf("%lld%lld", &a, &b)
#define ss(a) scanf("%s", a)
#define mem(a, b) memset(a, b, sizeof(a))
#define PII pair
using namespace std;
const int maxn = 1e5+5;
int cnt[maxn],a[maxn];
int main(){
int t;
sc(t);
while(t--){
int n,x;
sc(n);
mem(cnt,0);
//数组清零
for(int i=1;
i<=n;
i++){
sc(x);
cnt[x]++;
}
int bas=0,ca=0;
for(int i=1;
i<10;
i++){//找第一个非零
if(cnt[i]){
bas=i;
cnt[i]--;
break;
}
}
for(int i=1;
i<10;
i++){//找第一个非零
if(cnt[i]){
a[++ca]=i;
cnt[i]--;
break;
}
}
for(int i=0;
i<10;
i++){//从小到大加入
if(cnt[i]){
while(cnt[i]--){
a[++ca]=i;
}
}
}
string b;
for(int i=ca;
i>=1;
i--){//从个位开始乘
t+=bas*a[i];
b+=t%10+'0';
//存余数
t/=10;
//进位
}
if(t)b+=t+'0';
//最后进位
reverse(b.begin(),b.end());
//字符串反转
cout<
K-The Flee Plan of Groundhog 题意
- 有n个结点,n-1条边,小A从1号结点出发前往n号结点看望小B,每秒能走一条路
- t秒钟之后小B从n结点出发,来追小A,每秒能走两条路
- 问最迟要多久才能相遇
- 以n结点为根dfs递归建树。pre数组存放父节点,dep数组存放结点的深度,maxd数组存放子节点最深深度。
- n个结点,n-1条边,说明这是一棵树,所以小A从1出发去n只有一条路径,t秒之后小A的位置可以计算出来 。
- 求的是最迟相遇时间,那么小A就要远离小B,往树的深处跑,那么就有两种情况。
- 第一种情况,小A还没到树的最深处就被小B追上了。因为小B速度是小A的两倍,那么追逐时间其实就是两人的深度之差。
- 第二种情况,小A到最深处等小B。那么追逐时间就是小B到达最深处的时间。
#include
#define LL long long
#define sc(a) scanf("%d", &a)
#define sc2(a, b) scanf("%d%d", &a, &b)
#define sc3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define scl(a) scanf("%lld", &a)
#define scl2(a, b) scanf("%lld%lld", &a, &b)
#define ss(a) scanf("%s", a)
#define mem(a, b) memset(a, b, sizeof(a))
#define PII pair
using namespace std;
const int maxn = 1e5+5;
vectorv[maxn];
int pre[maxn],dep[maxn],maxd[maxn];
void add(int a,int b){
v[a].push_back(b);
v[b].push_back(a);
}
void dfs(int s,int fa){//dfs建树
for(auto i:v[s]){//遍历子树
if(i==fa)continue;
//不必跑父节点
pre[i]=s;
//存放父节点
dep[i]=dep[s]+1;
//子节点的深度等于父节点深度加1
maxd[i]=dep[i];
//存放子节点最深深度
dfs(i,s);
//向下递归
maxd[s]=max(maxd[s],maxd[i]);
//递归到根节点时,从下到上更新子节点最深深度
}
}
int main(){
int n,t;
sc2(n,t);
for(int i=1;
i
【2020牛客多校第九场 解题报告(AEFIK)】