Codeforces514

本文解析了几道算法竞赛题目,包括最小化数字、激光枪射击风暴兵的最少次数、字符串匹配查询、摧毁最大连续机器人序列及计算树节点数量等问题,提供了详细的代码实现。

这次考试题目顺序换过了,萎了,QAQ
Luke Skywalker gave Chewbacca an integer number x. Chewbacca isn’t good at numbers but he loves inverting digits in them. Inverting digit t means replacing it with digit 9 - t.

Help Chewbacca to transform the initial number x to the minimum possible positive number by inverting some (possibly, zero) digits. The decimal representation of the final number shouldn’t start with a zero.

Input
The first line contains a single integer x (1 ≤ x ≤ 1018) — the number that Luke Skywalker gave to Chewbacca.

Output
Print the minimum possible positive number that Chewbacca can obtain after inverting some digits. The number shouldn’t contain leading zeroes.

Example
Input
27
Output
22
Input
4545
Output
4444

本题水题,读入之后首位为9特判一下,其他情况就是一位位比较过去

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 19
int a[101];
char xx[101];
int len;
char c=1;
int main()
{
    len=0;
    while(!isdigit(c))
    {
        c=getchar();
    }
    while(isdigit(c))
    {
        a[++len]=c-'0';
        c=getchar();
    }
    for(int i=1;i<=len;i++)
    {
        if(i==1&&a[i]==9) continue;
        if(a[i]>4) a[i]=9-a[i];
    }
    for(int i=1;i<=len;i++) cout<<a[i];
}

**There are n Imperial stormtroopers on the field. The battle field is a plane with Cartesian coordinate system. Each stormtrooper is associated with his coordinates (x, y) on this plane.

Han Solo has the newest duplex lazer gun to fight these stormtroopers. It is situated at the point (x0, y0). In one shot it can can destroy all the stormtroopers, situated on some line that crosses point (x0, y0).

Your task is to determine what minimum number of shots Han Solo needs to defeat all the stormtroopers.

The gun is the newest invention, it shoots very quickly and even after a very large number of shots the stormtroopers don’t have enough time to realize what’s happening and change their location.

Input
The first line contains three integers n, x0 и y0 (1 ≤ n ≤ 1000,  - 104 ≤ x0, y0 ≤ 104) — the number of stormtroopers on the battle field and the coordinates of your gun.

Next n lines contain two integers each xi, yi ( - 104 ≤ xi, yi ≤ 104) — the coordinates of the stormtroopers on the battlefield. It is guaranteed that no stormtrooper stands at the same point with the gun. Multiple stormtroopers can stand at the same point.

Output
Print a single integer — the minimum number of shots Han Solo needs to destroy all the stormtroopers.

Example
Input
4 0 0
1 1
2 2
2 0
-1 -1
Output
2
Input
2 1 2
1 1
1 0
Output
1**
这题就是顺序扫一遍,一只只鸟扫过来打,看误伤了哪些去掉就行了。
计算几何推一发

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<new>
#include<queue>
#include<stack>
#include<fstream>
#define N 1001
using namespace std;
int x0,y0;
int x[N],y[N];
int n;
bool vis[N];
int ans;
bool pan(int s1,int s2)
{
    int x1=x[s1],x2=x[s2],y1=y[s1],y2=y[s2];
    if((y2-y1)*(x0-x1)==(y0-y1)*(x2-x1)) return 1;
    return 0;
}
int main()
{
    cin>>n>>x0>>y0;
    for(int i=1;i<=n;i++) cin>>x[i]>>y[i];
    for(int i=1;i<=n;i++)
    {
        if(vis[i]) continue;
        ans++;
        for(int j=i+1;j<=n;j++)
        {
            if(pan(i,j)) vis[j]=1;
        }
    }
    cout<<ans;
}

**Watto, the owner of a spare parts store, has recently got an order for the mechanism that can process strings in a certain way. Initially the memory of the mechanism is filled with n strings. Then the mechanism should be able to process queries of the following type: “Given string s, determine if the memory of the mechanism contains string t that consists of the same number of characters as s and differs from s in exactly one position”.

Watto has already compiled the mechanism, all that’s left is to write a program for it and check it on the data consisting of n initial lines and m queries. He decided to entrust this job to you.

Input
The first line contains two non-negative numbers n and m (0 ≤ n ≤ 3·105, 0 ≤ m ≤ 3·105) — the number of the initial strings and the number of queries, respectively.

Next follow n non-empty strings that are uploaded to the memory of the mechanism.

Next follow m non-empty strings that are the queries to the mechanism.

The total length of lines in the input doesn’t exceed 6·105. Each line consists only of letters ‘a’, ‘b’, ‘c’.

Output
For each query print on a single line “YES” (without the quotes), if the memory of the mechanism contains the required string, otherwise print “NO” (without the quotes).

Example
Input
2 3
aaaaa
acacaca
aabaa
ccacacc
caaac
Output
YES
NO
NO**

暴力跑trie树,我们理论证明了,这是不可能被卡掉的
为什么这时不会被卡掉的呢,证明比较玄学,我们知道输入最多也就30W个字符,而且字母就只有三种选择,首先我们考虑最卡的情况,此时所有trie树中的点都被遍历了1次,我们不妨将输入模板串和原串的字符各有60W,我们可以做到,让每次询问Trie树中所有节点都遍历1次,这个时候我们可以构造出一颗中间三叉两边挂链的树,我们设询问串和原串的长度均为x,是、则首先:我们不允许存在挂不下的情况。所以我们就考虑所有串都有点可挂。则可查询次数为60W/x,可遍历的节点的个数少于60W-x^2/2的,而且因为满足上述性质,所以(60W-x^2/2)

#include<bits/stdc++.h>
using namespace std;
#define N 100001
int xx[N];
int ans;
long long res=0;
int main()
{
    for(int x=1;x<=600000;x++)
    {
        long long i1=600000-(x*x)/2,i2=x*x;
        if(i1>i2)continue;
        long long hh=600000/x;
        long long it=hh*i1;
        if(it>res){res=it;ans=x;}
//      if(it<=0) break;
    }
    cout<<ans<<" "<<res;
}
%:pragma GCC optimize(4)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
int son[700001][4];
int n,m,k;
char s[600001];
int sz;
int root;
int zhuan='a'-1;
bool dance[700001];
bool have[700001];
bool hack(int ll,int rr,int it)
{
    int p=it;
    for(int i=ll;i<=rr;i++)
    {
        if(son[p][s[i]-zhuan])
        p=son[p][s[i]-zhuan];else return 0;
    }
    if(dance[p]) return 1;
    return 0;
}
bool check()
{
    int len=strlen(s+1);
    //大于会RE 
    int p=root;
    if(!have[len]) return 0;
    for(int i=1;i<=len;i++)
    {
        for(int kk=1;kk<=3;kk++)
        {
            if(kk!=s[i]-zhuan&&son[p][kk])
            if(hack(i+1,len,son[p][kk])||(i==len&&dance[son[p][kk]]))
            return 1;
        }
        if(son[p][s[i]-zhuan])p=son[p][s[i]-zhuan];else return 0;
    }
    return 0;
}
int main()
{
    cin>>n>>m;
    root=++sz;
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s+1);
        int len=strlen(s+1);
        have[len]=1;
        int p=root;
        for(int j=1;j<=len;j++)
        {
            if(!son[p][s[j]-zhuan]) son[p][s[j]-zhuan]=++sz;
            p=son[p][s[j]-zhuan];
        }
        dance[p]=1;
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%s",s+1);
        if(check())
        {
            puts("YES");
        }
        else puts("NO");
    }
}

An army of n droids is lined up in one row. Each droid is described by m integers a1, a2, …, am, where ai is the number of details of the i-th type in this droid’s mechanism. R2-D2 wants to destroy the sequence of consecutive droids of maximum length. He has m weapons, the i-th weapon can affect all the droids in the army by destroying one detail of the i-th type (if the droid doesn’t have details of this type, nothing happens to it).

A droid is considered to be destroyed when all of its details are destroyed. R2-D2 can make at most k shots. How many shots from the weapon of what type should R2-D2 make to destroy the sequence of consecutive droids of maximum length?

Input
The first line contains three integers n, m, k (1 ≤ n ≤ 105, 1 ≤ m ≤ 5, 0 ≤ k ≤ 109) — the number of droids, the number of detail types and the number of available shots, respectively.

Next n lines follow describing the droids. Each line contains m integers a1, a2, …, am (0 ≤ ai ≤ 108), where ai is the number of details of the i-th type for the respective robot.

Output
Print m space-separated integers, where the i-th number is the number of shots from the weapon of the i-th type that the robot should make to destroy the subsequence of consecutive droids of the maximum length.

If there are multiple optimal solutions, print any of them.

It is not necessary to make exactly k shots, the number of shots can be less.

Example
Input
5 2 4
4 0
1 2
2 1
0 2
1 3
Output
2 2
Input
3 2 4
1 2
1 3
2 2
Output
1 3
Note
In the first test the second, third and fourth droids will be destroyed.

In the second test the first and second droids will be destroyed.
其实这道题两个指针狂扫即可,但我只想到了二分答案+线段树的做法所以就可以AC了,二分新姿势get!

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<new>
#include<queue>
using namespace std;
#define N 500001
#define M 8
int L[N],R[N],val[N][M],lazy[N][M],n,m,k;
int l,r;
bool flag=0;
int xx[M];
int a[N][M];
void build(int no,int l,int r)
{
    L[no]=l;R[no]=r;
    if(l==r) 
    {
        for(int i=1;i<=m;i++)
        val[no][i]=a[l][i];
        return;
    }
    int mid=(l+r)>>1;
    build(no*2,l,mid);
    build(no*2+1,mid+1,r);
    for(int i=1;i<=m;i++)
    {
        val[no][i]=max(val[no*2][i],val[no*2+1][i]);
    }
    return;
}
int query(int ty,int no,int l,int r)
{
    if(L[no]==l&&R[no]==r) return val[no][ty];
    int mid=(L[no]+R[no])>>1;
    if(l>mid) return query(ty,no*2+1,l,r);
    if(r<=mid) return query(ty,no*2,l,r);
    return max(query(ty,no*2,l,mid),query(ty,no*2+1,mid+1,r));
}
int ans[M];
bool pan(int x)
{
    if(x==0) return 1;
    for(int b=1;b<=n-x+1;b++)
    {
        memset(xx,0,sizeof(xx));
        int sum=0;
        for(int i=1;i<=m;i++)
        {
            xx[i]=query(i,1,b,b+x-1);
            sum+=xx[i];
        }
        if(sum<=k) 
        {
            for(int i=1;i<=m;i++)
            ans[i]=xx[i];
            return 1;
        }   
    }
    return 0;
}
void print()
{
    for(int i=1;i<=m;i++)cout<<ans[i]<<" ";
}
int main()
{
    cin>>n>>m>>k;
    l=0;r=n;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        cin>>a[i][j];
    }
    build(1,1,n);
    while(l<=r)//要小于等于 
    {
        int mid=(l+r)>>1;
        if(pan(mid))
        {
            l=mid+1;
        }
        else r=mid-1;
    }
    print();
}

When Darth Vader gets bored, he sits down on the sofa, closes his eyes and thinks of an infinite rooted tree where each node has exactly n sons, at that for each node, the distance between it an its i-th left child equals to di. The Sith Lord loves counting the number of nodes in the tree that are at a distance at most x from the root. The distance is the sum of the lengths of edges on the path between nodes.

But he has got used to this activity and even grew bored of it. ‘Why does he do that, then?’ — you may ask. It’s just that he feels superior knowing that only he can solve this problem.

Do you want to challenge Darth Vader himself? Count the required number of nodes. As the answer can be rather large, find it modulo 109 + 7.

Input
The first line contains two space-separated integers n and x (1 ≤ n ≤ 105, 0 ≤ x ≤ 109) — the number of children of each node and the distance from the root within the range of which you need to count the nodes.

The next line contains n space-separated integers di (1 ≤ di ≤ 100) — the length of the edge that connects each node with its i-th child.

Output
Print a single number — the number of vertexes in the tree at distance from the root equal to at most x.

Example
Input
3 3
1 2 3
Output
8

本题是神奇的矩阵优化,先贴一发暴力,说明一下DP方法

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
using namespace std;
map<int,long long>M;
int n,x;
int a[100001];
#define r(x) scanf("%d",&x)
set<int>it;
int pg[101];
int sum;
long long mod=1e9+7;
long long dfs(int x)
{
    long long ans=1;
    if(x<=300000)
    if(M.count(x)) return M[x];
    if(x==0) return 1;
    for(int i=1;i<=100;i++)
    {
        if(pg[i]&&x>=i)
        ans+=(pg[i]*dfs(x-i))%mod;
        ans=ans%mod;
    }
    if(x<=300000)
    M[x]=ans;
    return ans;
}
int main()
{
    r(n);r(x);
    for(int i=1;i<=n;i++) r(a[i]);
    for(int i=1;i<=n;i++) pg[a[i]]++;
    cout<<dfs(x)%mod<<endl;
}

然后就是可以构造矩阵,这其实是类似一个模板,我们对于任何一维的需要前面状态有限的线性DP可以如下构造:
就是构造第一行放着一大堆系数,然后下面每条对角线放一,然后每乘一次就会滚动一次,然后我们有常数1,所以在最后一列上放上1在DP矩阵最后加一行1,就可以实现,矩阵快速幂优化DP

#include<cstdio>
#include<iostream>
using namespace std;
#define N 101
struct ret{
    long long xx[102][102];
}it,dancer,f[32];
int n,m;
int pg[101];
int x,y;
const long long mod=1e9+7;
#define r(x) scanf("%d",&x)
ret firedancer;
ret cheng(ret x,ret y)
{
    for(int i=1;i<=101;i++)
    for(int j=1;j<=101;j++)
    {
        long long t=0;
        for(int k=1;k<=101;k++)
        {
            t+=x.xx[i][k]*y.xx[k][j];
            t=t%mod;
        }
        firedancer.xx[i][j]=t;
    }
    return firedancer;
}
int main()
{
    r(n);r(m);
    for(int i=1;i<=n;i++)
    {
        r(y);pg[y]++;
    }
    dancer.xx[1][1]=1;dancer.xx[1][101]=1;
    for(int i=2;i<=100;i++) f[0].xx[i-1][i]=1;
    for(int i=1;i<=100;i++) f[0].xx[i][1]=pg[i];
    f[0].xx[101][1]=1;f[0].xx[101][101]=1;
    for(int i=1;i<=30;i++)
    {
        f[i]=cheng(f[i-1],f[i-1]);
    }
    int cnt=0;
    while(m)
    {
        if(m%2)
        dancer=cheng(dancer,f[cnt]);
        m>>=1;
        cnt++;
    }
    cout<<dancer.xx[1][1];
}
c++14 ## 题目描述 你是一个高维空间魔术师,手上有一个最初维度为 $n$ 维的超立方体,给定每一维的边长为 $a_1, a_2, \dots, a_n$。对于一个 $d$ 维的超立方体,定义其各维度边长和为 $\sum_{i=1}^d a_i$,超体积为 $\prod_{i=1}^d a_i$。 你想得到一个各维度边长和为 $S$,超体积为 $M$ 的超立方体,于是决定将手上现有的超立方体进行降维操作和升维操作。 - 降维操作:删去一个维度。 - 升维操作:加入一个维度,该维度边长可以是任意的正整数。 无论升维还是降维操作都非常消耗精力,因此你想知道最少需要通过多少次操作,才能得到一个各维度边长和为 $S$,超体积为 $M$ 的超立方体。 ## 输入格式 第一行三个整数 $n, S, M$ ($1\le n \le 10^5$, $1 \le S, M \le 10^{10}$)。 第二行 $n$ 个整数,表示初始超立方体的每个维度的边长 $a_i$ ($1 \le a_i \le 10^{10}$)。 ## 输出格式 输出一个整数,表示最小操作次数。如果无法得到满足条件的立方体,输出 $-1$。 ## 输入输出样例 #1 ### 输入 #1 ``` 2 5 6 1 2 ``` ### 输出 #1 ``` 2 ``` ## 输入输出样例 #2 ### 输入 #2 ``` 3 6 5 1 2 3 ``` ### 输出 #2 ``` 3 ``` ## 输入输出样例 #3 ### 输入 #3 ``` 2 114514 735134400 114 514 ``` ### 输出 #3 ``` 20 ``` ## 输入输出样例 #4 ### 输入 #4 ``` 2 4 7 1 3 ``` ### 输出 #4 ``` -1 ``` ## 说明/提示 对于第一个样例,一种可行的方法是:先删去边长为 $1$ 的维度,然后加入一个边长为 $3$ 的维度。
最新发布
12-21
### Codeforces 平台概述 Codeforces 是一个广受认可的在线编程竞赛平台,专注于算法竞技与程序设计能力提升[^1]。该平台由俄罗斯萨拉托夫州立大学的 Mike Mirzayanov 创建,自 2010 年上线以来已成为全球最具影响力的编程竞赛网站之一。 ### 编程竞赛机制 平台上定期举行名为 “Codeforces Round” 的定时竞赛,通常每两周一次,每次持续两小时左右。比赛采用分等级制度(Div. 1 和 Div. 2),根据参赛者当前 Rating 进行划分,确保公平竞争环境[^7]。近年来也推出了更灵活的比赛形式,如 Educational Rounds、Global Rounds 及 Team Contests,进一步丰富了赛事生态[^8]。 竞赛题目一般设置为 5 到 7 道不等,按难度递增标记为 A 至 G 级别。其中 A 题为基础模拟或贪心类问题,适合初学者;B/C 类常考察构造逻辑或多步推理;D/E 题则深入图论、动态规划、数论等领域;F/G 多用于高级技巧如复杂数据结构组合、概率期望推导等[^9]。 ```cpp // 示例:简单实现快速幂取模——常见于处理大指数运算场景 long long mod_pow(long long base, long long exp, long long mod) { long long result = 1; while (exp > 0) { if (exp & 1) result = (result * base) % mod; base = (base * base) % mod; exp >>= 1; } return result; } ``` ### 在线判题系统运作方式 提交代码后,系统会自动运行预设测试用例并返回反馈状态,包括 Accepted (AC)、Wrong Answer (WA)、Time Limit Exceeded (TLE)、Memory Limit Exceeded (MLE) 等结果码[^10]。评测基于 GNU C++ 编译器标准(常用 g++-x.x)、内存限制(通常 256MB)和时间约束(多数单测 ≤2 秒)。选手需注意输入输出效率优化,推荐使用 `scanf/printf` 或关闭同步流 (`ios::sync_with_stdio(false);`) 提升性能[^11]。 ### 算法题目特点与解题策略 Codeforces 的题目强调思维训练而非工程实践,典型考点覆盖: - **基础算法**:二分查找、前缀和、差分数组 - **经典结构**:栈、队列、优先队列、哈希表 - **高阶主题**:树状数组(BIT)、线段树、LCA 查询、网络流 部分难题融合多个知识点,例如 [Problem 1601F - Two Sorts] 要求结合排序理论与 ST 表技术,在离散化后的序列上维护区间最值映射关系,并考虑偏移量加减对位置索引的影响[^3]。 这类综合型挑战推动参与者掌握跨领域建模技能,同时也促进 STL 容器熟练运用与底层原理理解。 ### 社区影响与发展现状 截至近年统计数据显示,Codeforces 注册用户已突破百万级,来自超过 200 个国家和地区。其举办的 ICPC 训练营合作项目、Google Kick Start 前哨赛联动等活动显著提升了国际间青少年计算机教育互动频率[^12]。知名高校如 MIT、Stanford 将其作为选拔 ACM 国际队伍的重要参考依据之一。 活跃度方面,Top Rated 用户长期保持高强度刷题节奏,最高 Rating 曾达 4000+(tourist 保持历史纪录多年),反映出顶尖群体的技术沉淀强度[^13]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值