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\) 顶点的连通块,连通块的权值为连接块内这些点的边权和. 求一种选法,使得这个选法的权值是所有选法中第 \ ...
随机推荐
- [转帖]备忘:CentOS-7 使用systemctl 管理的服务,文件打开数上限1024要改
备忘:CentOS-7 使用systemctl 管理的服务,文件打开数上限1024要改 https://blog.csdn.net/toontong/article/details/50440272 ...
- PostgreSQL编码格式:客户端服务器、客户端、服务器端相关影响
关于字符编码这块,官网链接: https://www.postgresql.org/docs/current/charset.html 刚刚写了几百字的东西因为断网,导致全没有了,重头再写,我就只想记 ...
- pycharm 更换源 Windows Linux平台
pycharm 更换源 Windows Linux平台 参考资料:https://blog.csdn.net/wls666/article/details/95456309 Windows下更新源 文 ...
- Eratosthenes筛法
复杂度为nlogn. 算法思想为:枚举1~sqrt(n),然后把每一个数的倍数都都打上不是素数的标记. 还要特别注意0,1不是素数,打标记枚举到i*k<=n. 代码如下 #include< ...
- python基础_面向对象
面向对象定义 把一组数据结构和处理它们的方法组成对象(object),把相同行为的对象归纳为类(class),通过类的封装(encapsulation)隐藏内部细节,通过继承(inheritance) ...
- nginx+gunicorn/uwsgi+python web 的前世今生
我们在部署 flask.django 等 python web 框架时,网上最多的教程就是 nginx+gunicorn/uwsgi 的部署方式,那为什么要这么部署呢,本文就来系统地解释这个问题. 必 ...
- PHP 下载mysql数据到PHPExcel表格
第一步:先到官网(https://github.com/PHPOffice/PHPExcel)下载PHPExcel 第二步:放到第三方库 第三步: /** * 封装:信息导出 * @param $da ...
- MySQL存储引擎知多少
MySQL是我们经常使用的数据库处理系统(DBMS),不知小伙伴们有没有注意过其中的“存储引擎”(storage_engine)呢?有时候面试题中也会问道MySQL几种常用的存储引擎的区别.这次就简短 ...
- 10 Scrapy框架持久化存储
一.基于终端指令的持久化存储 保证parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作. 执行输出指定格式进行存储:将爬取到的 ...
- Javascript问题集锦
1.Date.parse()函数兼容性问题: IE Chrome Firefox Date.parse("07-17-2019") 1563292800000 15632928 ...