HGOI20190811 省常中互测4
Problem A magic
给出一个字符串$S$,和数字$n$,要求构造长度为$n$只含有小写字母的字符串$T$,
使得在$T$中存在删除且仅删除一个子串使得$S=T$成立。
输出$T$的构造方案数,mod 998244353的值。
对于$100 \% $的数据 $2 \leq n \leq 10^{18} , |S| \leq 10^6$
Sol : 考虑$T$合法的条件是和$S$有相同的前缀和相同的后缀,且相同前后缀长度和是$|S|$
若最长公共前缀长度为$0$ ,那么说明$S$和$T$最后$|S|$位相同,合法情况$T$的取值有$26^{n - |S|}$ 种。
若最长公共前缀长度不为$0$ ,那么说明前半部分至少有$k$是$S$的前缀,后半部分就有$|S| - k $的长度是后缀,这个时候由于倒数$|S| - k$ 个 不能和上一次一样,这个位置只有$25$种可能,其他位置是$26$种可能,这种情况下方案数时$26^{n-|S|-1}$
最后答案就是$26^n - 26^{n-1} - |S|\times 25 \times 26^{n-|S|-1}$
注意需要特判$n = |S|$的情况,答案就是$26 ^ n - 1$
复杂度是$O(log_2 n)$
#include<bits/stdc++.h>
using namespace std;
const long long mod=;
long long n,m;
char tmp[];
long long Pow(long long x,long long k)
{
if(k<) return 0ll;
if(!k) return 1ll;
long long res=Pow(x,k/);
res=res*res%mod;
if(k%) res=res*x%mod;
return res;
}
int main()
{
scanf("%lld %s",&n,tmp);
m=strlen(tmp);
printf("%lld",(long long)(Pow(26ll,n)-(Pow(26ll,n-m)%mod+(m*25ll%mod)*Pow(26ll,n-m-)%mod)%mod+mod)%mod);
return ;
}
A.cpp
Problem B graph
给出可重边无自环不保证连通的无向图$G$ ,询问$u $到$v$简单路径上经过边权的最大值最小。
对于$100\% $ 的数据$n,m,q \leq 3 \times 10^5$
Sol: 建出最小生成树(在建树过程考虑了重边了)。、
然后用并查集维护连通性。
最大边权最小等价于在最小生成树树上路径的最大值。
复杂度就是$O(m log_2 m)$
# include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + ;
map<int,int>mp[N];
int g[N][],d[N][],dep[N],fc[N],n,m,q;
vector<pair<int , int> >E[N];
struct edge{
int u,v,w;
};
vector<edge>Edge;
bool cmp(edge a,edge b){return a.w < b.w;}
inline int read()
{
int X=,w=; char c=;
while(c<''||c>'') {w|=c=='-';c=getchar();}
while(c>=''&&c<='') X=(X<<)+(X<<)+(c^),c=getchar();
return w?-X:X;
}
void write(int x)
{
if (x<) x=-x,putchar('-');
if (x>) write(x/);
putchar(''+x%);
}
void writeln(int x)
{
write(x); putchar('\n');
}
int father(int x)
{
if (fc[x]==x) return x;
return fc[x]=father(fc[x]);
}
void kruskal()
{
sort(Edge.begin(),Edge.end(),cmp);
for (int i = ; i <= n; i++) fc[i] = i;
for (int i = ; i < Edge.size(); i++) {
int u=Edge[i].u,v=Edge[i].v,w=Edge[i].w;
int fx = father(Edge[i].u),fy = father(Edge[i].v);
if (fx == fy) continue;
fc[fx] = fy;
E[u].push_back(make_pair(v,w));
E[v].push_back(make_pair(u,w));
}
}
void dfs(int u,int fa)
{
dep[u]=dep[fa]+; g[u][]=fa;
for (int i=;i<E[u].size();i++) {
int v=E[u][i].first,w=E[u][i].second;
if (v==fa) continue;
d[v][]=w;
dfs(v,u);
}
}
void init()
{
for (int i = ; i<=n ; i++)
if (!dep[i]) dfs(i,);
for (int i = ; i <= ; i++)
for (int j = ; j <= n ; j++)
g[j][i] = g[g[j][i-]][i-],
d[j][i] = max(d[j][i-] , d[g[j][i-]][i-]);
}
int query(int u,int v)
{
int fx = father(u), fy = father(v);
if (fx != fy) return -;
if (dep[u] < dep[v]) swap(u,v);
int ret = ;
for (int i = ; i >= ; i--)
if (dep[g[u][i]] >= dep[v])
ret = max(ret,d[u][i]),u=g[u][i];
if (u == v) return ret;
for (int i = ; i >= ;i--)
if (g[u][i] != g[v][i])
ret = max(max(ret , d[u][i]) , d[v][i]),
u = g[u][i] , v = g[v][i];
return max(max(ret,d[u][]),d[v][]);
}
int main()
{
n=read();m=read();q=read();
for (int i=;i<=m;i++) {
int u=read(),v=read(),w=read();
if (mp[u].count(v) != ) w = min(w , mp[u][v]);
mp[u][v] = mp[v][u] = w;
}
map<int,int>::iterator it;
for (int i = ; i <= n ; ++i )
for (it = mp[i].begin() ; it != mp[i].end() ; ++it)
Edge.push_back((edge){i , it->first , it->second});
kruskal(); init();
while (q--) {
int u=read(),v=read();
writeln(query(u,v));
}
return ;
}
B.cpp
Problem C number
定义不算前导零,只由两个数字构成的数为“好数”,如$101010$, $11111$
给出$T$个询问,询问$x$至少由几个好数相加组成的(可以同一个数用多次)。
对于$100\%$的数据$1 \leq n \leq 10^{18} ,1 \leq T \leq 100$
Sol:考虑$01$ , $02$ , $03$ , $04$最多四个数字就可以创造世界了,所以我们只需要判断$3$及以下的情况,剩余情况就输出$4$
我们可以枚举$C_{10}^{2} = 45$种选择数的方案$mask[i]$来构成这些数,然后用dp验证即可。
我们只至少这若干个数加起来是多少,我们要还原他为0,才能检验是否合法。
对于每个三个数累加的方案,我们都有这三个数中任意选2个任意选1个不选这7种子方案,也能获得相同的效果,我们特殊考虑,记录在$Sub[i]$中。
我们可以预处理出每个个选择数的方案,可以构成哪些最小合法的数(显然这些数都是小于等于$3 \times 9 =27$的)
设$f[i][j]$表示使用标号为$i$的方案,到达$j$数位上的信息,这个信息是一个3位二进制数,分别表示高位向低位退位为$i , i\in[0,2]$是否合法。
转移的话可以用位运算转移。
最后如果当前数位为1,并且可以退0位的方案是ok的,那么我们就对对应取数的个数求min即可。(如果无法构成答案就是4了)
复杂度是$O(T \times C_{45}^{3} \times 18 \times 3 \times 3)$
# include <bits/stdc++.h>
# define int long long
using namespace std;
int mask[],f[][],s[][][],val[],a[];
bool ok[][];
int size;
vector<int>Sub[];
signed main()
{
for (int i = ; i <= ; i++ )
for (int j = i + ; j <= ; j++ )
mask[++mask[]] = i * + j;
memset(ok, false, sizeof(ok));
int t = mask[] ; mask[] = ;
for (int i = ;i <= t ; i++)
for (int j = i ; j <= t ; j++)
for (int k = j ; k <= t ;k++) {
val[++size] = - (i==) - (j==) - (k==);
ok[size][mask[i]/ + mask[j]/ + mask[k]/] = ok[size][mask[i]% + mask[j]/ + mask[k]/] = true;
ok[size][mask[i]/ + mask[j]% + mask[k]/] = ok[size][mask[i]/ + mask[j]/ + mask[k]%] = true;
ok[size][mask[i]% + mask[j]% + mask[k]/] = ok[size][mask[i]% + mask[j]/ + mask[k]%] = true;
ok[size][mask[i]/ + mask[j]% + mask[k]%] = ok[size][mask[i]% + mask[j]% + mask[k]%] = true;
s[i][j][k] = s[i][k][j] = s[j][i][k] = s[j][k][i] = s[k][i][j] = s[k][j][i] = size;
if (s[][j][k] != size) Sub[size].push_back(s[][j][k]);
if (s[i][][k] != size) Sub[size].push_back(s[i][][k]);
if (s[i][j][] != size) Sub[size].push_back(s[i][j][]);
if (s[][][k] != size) Sub[size].push_back(s[][][k]);
if (s[][j][] != size) Sub[size].push_back(s[][j][]);
if (s[i][][] != size) Sub[size].push_back(s[i][][]);
if (s[][][] != size) Sub[size].push_back(s[][][]);
}
int T; scanf("%lld",&T);
while (T--) {
memset(f, , sizeof(f));
int x; scanf("%lld",&x); a[] = ;
while (x) { a[++a[]] = x%; x/=;}
for (int i = ; i<= size; i++) f[i][a[]+] = ;
for (int i = a[] ; i>= ; i--) {
for (int j = ; j <= size ; j++) {
for (int last = ; last <= ; last++) if (f[j][i+] & (<<last))
for (int to = ; to <= ; to++) if (last* + a[i] - to >= && ok[j][last* + a[i] - to]) {
f[j][i] |= (<<to) ;
}
for (int k = ;k < Sub[j].size() ; k++) {
int tmp = Sub[j][k] ;
f[j][i] |= f[tmp][i];
}
}
}
int ans = ;
for (int i = ; i <= size ; i++) if (f[i][] & ) ans = min(ans , val[i]);
printf("%lld\n",ans);
}
return ;
}
C.cpp
HGOI20190811 省常中互测4的更多相关文章
- HGOI 20190816 省常中互测8
Problem A 有两条以(0,0)为端点,分别经过(a,b),(c,d)的射线,你要求出夹在两条射线中间,且距离(0,0)最近的点(x,y) 对于$100\%$的数据满足$1 \leq T \l ...
- HGOI20190814 省常中互测7
Problem A 中间值 对于$2$个非严格单增序列$\{A_n\} , \{B_n\}$,维护下列两个操作: 1 x y z: (x=0)时将$A_y = z$ , (x=1)时将$B_y = z ...
- HGOI20190813 省常中互测6
Problem A 蛋糕 将$n \times m $大小的蛋糕切成每块为$1 \times 1$大小的$n\times m$块. 交换任意两块蛋糕的切割顺序的方案算作一种. 对于$100 \%$的数 ...
- HGOI20190810 省常中互测3
Problem A 夏洛特 若当前处在点$(x,y)$下一时刻可以向该点四周任意方向走动一步, 初始在$(0,0)$是否存在一条合法的路线满足下列$n$个限制: 每一个限制形如$t_i , x_i ...
- HGOI20190809 省常中互测2
Problem A 时之终结 构造一个含有$n$个节点的无重边无自环的有向图, 使得从$1$出发,每一次经过一条$(u,v) (u < v)$的边到达节点$n$的方案恰好有$y$种. 对于$10 ...
- HGOI20190808 省常中互测1
Problem A sum 给出$n$个元素的序列$\{a_i\}$,求出两个不相交连续子序列的最大元素和. 即对于$1 \leq A \leq B \leq C \leq D \leq n$最大化 ...
- HGOI20190812 省常中互测5
Task 1 辩论 有N 个参加辩论的候选人,每个人对这两个议题都有明确的态度,支持或反对.作为组织者,小D 认真研究了每个候选人,并给每个人评估了一个非负的活跃度,他想让活跃度之和尽可能大.选出的候 ...
- 【2018集训队互测】【XSY3372】取石子
题目来源:2018集训队互测 Round17 T2 题意: 题解: 显然我是不可能想出来的……但是觉得这题题解太神了就来搬(chao)一下……Orzpyz! 显然不会无解…… 为了方便计算石子个数,在 ...
- 【CH 弱省互测 Round #1 】OVOO(可持久化可并堆)
Description 给定一颗 \(n\) 个点的树,带边权. 你可以选出一个包含 \(1\) 顶点的连通块,连通块的权值为连接块内这些点的边权和. 求一种选法,使得这个选法的权值是所有选法中第 \ ...
随机推荐
- PHP中的接口
对象接口 使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容. 接口是通过 interface 关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方 ...
- Microsoft SQL server 2012数据库学习总结(一)
一.Microsoft SQL Server2012简介 1.基本概要 Microsoft SQL Server 2012是微软发布的新一代数据平台产品,全面支持云技术与平台,并且能够快速构建相应的解 ...
- orzdba工具配置
./orzdba -lazy -rt -S /u01/svr/working/my3306/run/mysql.sock mysql -s --skip-column-names -h127.0.0. ...
- [BJOI2014]大融合(Link Cut Tree)
[BJOI2014]大融合(Link Cut Tree) 题面 给出一棵树,动态加边,动态查询通过每条边的简单路径数量. 分析 通过每条边的简单路径数量显然等于边两侧节点x,y子树大小的乘积. 我们知 ...
- Python 入门 之 初识面向对象
Python 入门 之 初识面向对象 1.初识面向对象编程 (核心--对象) (1)观察以下代码: # 面向过程编程 s = "alexdsb" count = 0 for i i ...
- etcd集群安装
etcd 是一个分布式一致性k-v存储系统,可用于服务注册发现与共享配置,具有以下优点:1.简单:相比于晦涩难懂的paxos算法,etcd基于相对简单且易实现的raft算法实现一致性,并通过gRPC提 ...
- CALL apoc.cypher.doIt创建动态节点的时候怎么指定多个标签?
下面的创建节点实例,请教一下CALL apoc.cypher.doIt如何创建多个标签?现在的方式是只能指定一个标签! UNWIND [{name:"sdasdsad234fdgsasdfa ...
- 基于CentOS系统部署EPICS环境
1.虚拟机安装CentOS系统2.打开终端,以root账户登录3.进入/usr/local目录下,新建文件夹epics,并进入该文件夹4.在/usr/local/epics目录下,执行wget htt ...
- CentOS下安装DockerCE
title: CentOS下安装DockerCE comments: false date: 2019-09-04 09:47:58 description: 在CentOS下安装社区版Docker ...
- css之盒模型(box,box-shadow,overflow,BFC)
一.盒模型的概念 CSS中每一个元素都是一个盒模型(Box Model),包括HTML和body标签元素.一般称之为box model.它的本质就是一个盒子,它的属性有margin,border,pa ...