Codeforces Round #423 Div. 1
A:暴力赋值即可,并查集维护下一个未被赋值的位置。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 2000010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int T,fa[N],len;
char s[N],ans[N];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
T=read();
for (int i=1;i<=2000001;i++) fa[i]=i;
while (T--)
{
scanf("%s",s);int m=strlen(s);
int n=read();
for (int i=1;i<=n;i++)
{
int x=read();
len=max(len,x+m-1);
for (int j=find(x);j<=x+m-1;j=find(j))
ans[j]=s[j-x],fa[j]=find(j+1);
}
}
for (int i=1;i<=len;i++)
if (find(i)==i) ans[i]='a';
printf("%s",ans+1);
return 0;
//NOTICE LONG LONG!!!!!
}
B:显然应该连成菊花套链。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 200010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,k;
bool flag[N];
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
cin>>n>>k;
if (n%k==2||k==2&&n%k==0) cout<<2*((n-2)/k)+1<<endl;
else if (n%k==1) cout<<2*((n-1)/k)<<endl;
else cout<<2*((n-1)/k+1)<<endl;
for (int i=1;i<=k;i++) flag[i]=1;
for (int i=k+1;i<n;i++)
{
flag[i-k]=0;flag[i]=1;
printf("%d %d\n",i-k,i);
}
for (int i=1;i<=n;i++) if (flag[i]) printf("%d %d\n",n,i);
return 0;
//NOTICE LONG LONG!!!!!
}
C:注意到字符集大小很小询问串长度很短,对每种字符每种长度分别维护bit即可。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 100010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
char s[N],t[N];
int n,q,tree[4][11][N];
int trans(char c)
{
if (c=='A') return 0;
if (c=='T') return 1;
if (c=='G') return 2;
if (c=='C') return 3;
}
int nxt(int x,int m,int r)
{
if (x>r) x-=m;
return x+(r-x)/m*m;
}//<=r u mod m=x mod m
void add(int x,int m,int k,int p)
{
while (k<=n)
{
tree[x][m][k]+=p;
int u=(k-1)/m+1;
u+=u&-u;
k=(u-1)*m+(k-1)%m+1;
}
}
int query(int x,int m,int k)
{
if (k<=0) return 0;
int s=0;
while (k>0)
{
s+=tree[x][m][k];
int u=(k-1)/m+1;
u-=u&-u;
k=(u-1)*m+(k-1)%m+1;
}
return s;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
scanf("%s",s+1);
n=strlen(s+1);
for (int i=1;i<=n;i++)
for (int j=1;j<=10;j++)
add(trans(s[i]),j,i,1);
q=read();
while (q--)
{
int op=read();
if (op==1)
{
int x=read();
char c=getc();
for (int j=1;j<=10;j++)
add(trans(s[x]),j,x,-1),
add(trans(c),j,x,1);
s[x]=c;
}
else
{
int l=read(),r=read();
scanf("%s",t);int m=strlen(t),ans=0;
for (int i=0;i<m;i++) ans+=query(trans(t[i]),m,nxt(l+i,m,r))-query(trans(t[i]),m,l+i-m);
printf("%d\n",ans);
}
}
return 0;
//NOTICE LONG LONG!!!!!
}
D:先跑一棵MST。对于不在MST中的边,显然要使其满足条件,其权值应比MST中两点路径上的权值最大值小。倍增查一下即可。对于在MST上的边,其权值应比所有覆盖该边的非树边权值小。从小到大进行树链覆盖,并查集维护每个点第一个未被覆盖的祖先即可。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 200010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m,p[N],dfn[N],f[N],deep[N],fa[N][19],E[N],ans[N],len[N][20],t,cnt;
bool flag[N];
struct data{int to,nxt,i,len;
}edge[N<<1];
struct data2
{
int x,y,z,i;
bool operator <(const data2&a) const
{
return z<a.z;
}
}e[N];
void addedge(int x,int y,int i,int z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].i=i,edge[t].len=z,p[x]=t;}
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
void dfs(int k)
{
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=fa[k][0])
{
fa[edge[i].to][0]=k;
E[edge[i].to]=edge[i].i;
len[edge[i].to][0]=edge[i].len;
deep[edge[i].to]=deep[k]+1;
dfs(edge[i].to);
}
}
int lca(int x,int y)
{
if (deep[x]<deep[y]) swap(x,y);
for (int j=18;~j;j--) if (deep[fa[x][j]]>=deep[y]) x=fa[x][j];
if (x==y) return x;
for (int j=18;~j;j--) if (fa[x][j]!=fa[y][j]) x=fa[x][j],y=fa[y][j];
return fa[x][0];
}
void cover(int x,int u,int y)
{
x=find(x);
while (deep[x]>deep[u])
{
ans[E[x]]=y-1;
f[x]=find(fa[x][0]);
x=find(x);
}
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read(),m=read();
for (int i=1;i<=m;i++) e[i].x=read(),e[i].y=read(),e[i].z=read(),e[i].i=i;
sort(e+1,e+m+1);
for (int i=1;i<=n;i++) f[i]=i;
for (int i=1;i<=m;i++)
if (find(e[i].x)!=find(e[i].y))
{
f[find(e[i].x)]=find(e[i].y);
addedge(e[i].x,e[i].y,e[i].i,e[i].z),addedge(e[i].y,e[i].x,e[i].i,e[i].z);
flag[i]=1;
}
fa[1][0]=1;dfs(1);
for (int j=1;j<=18;j++)
for (int i=1;i<=n;i++)
fa[i][j]=fa[fa[i][j-1]][j-1],
len[i][j]=max(len[i][j-1],len[fa[i][j-1]][j-1]);
for (int i=1;i<=n;i++) f[i]=i;
for (int i=1;i<=m;i++)
if (!flag[i])
{
int x=e[i].x,y=e[i].y,u=lca(x,y);
cover(x,u,e[i].z);cover(y,u,e[i].z);
for (int j=18;~j;j--)
{
if (deep[fa[x][j]]>=deep[u]) ans[e[i].i]=max(ans[e[i].i],len[x][j]),x=fa[x][j];
if (deep[fa[y][j]]>=deep[u]) ans[e[i].i]=max(ans[e[i].i],len[y][j]),y=fa[y][j];
}
ans[e[i].i]--;
}
for (int i=2;i<=n;i++) if (find(i)==i) ans[E[i]]=-1;
for (int i=1;i<=m;i++) printf("%d ",ans[i]);
return 0;
//NOTICE LONG LONG!!!!!
}
E:考虑如何判断某循环节长度是否合法,显然只要不存在字符不同(不包括?)的距离为其倍数的两位置即可。考虑求每种距离各有多少对字符不同。https://www.cnblogs.com/Gloid/p/9452441.html。然后暴力枚举倍数判断即可。略卡常,似乎FFT比NTT快。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 1100000
#define P 998244353
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int T,n,a[N],b[N],c[N],f[N],r[N],ans[N];
char s[N];
void inc(int &x,int y){x+=y;if (x>=P) x-=P;}
int ksm(int a,int k)
{
int s=1;
for (;k;k>>=1,a=1ll*a*a%P) if (k&1) s=1ll*s*a%P;
return s;
}
int inv(int a){return ksm(a,P-2);}
void DFT(int *a,int n,int g)
{
for (int i=0;i<n;i++) r[i]=(r[i>>1]>>1)|(i&1)*(n>>1);
for (int i=0;i<n;i++) if (i<r[i]) swap(a[i],a[r[i]]);
for (int i=2;i<=n;i<<=1)
{
int wn=ksm(g,(P-1)/i);
for (int j=0;j<n;j+=i)
{
int w=1;
for (int k=j;k<j+(i>>1);k++,w=1ll*w*wn%P)
{
int x=a[k],y=1ll*w*a[k+(i>>1)]%P;
a[k]=(x+y)%P,a[k+(i>>1)]=(x-y+P)%P;
}
}
}
}
void mul(int *a,int *b,int n)
{
DFT(a,n,3),DFT(b,n,3);
for (int i=0;i<n;i++) a[i]=1ll*a[i]*b[i]%P;
DFT(a,n,inv(3));
int t=inv(n);
for (int i=0;i<n;i++) a[i]=1ll*a[i]*t%P;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
T=read();
while (T--)
{
n=read();scanf("%s",s+1);
int t=1;while (t<(n<<1)) t<<=1;
for (int i=0;i<t;i++) a[i]=b[i]=c[i]=0;
for (int i=0;i<t;i++) f[i]=0;
for (int i=1;i<=n;i++) if (s[i]=='V') a[i]=1;
for (int i=0;i<n;i++) f[i]=2*(s[n-i]=='K');
mul(a,f,t);
for (int i=0;i<t;i++) f[i]=0;
for (int i=1;i<=n;i++) if (s[i]=='K') b[i]=8;
for (int i=0;i<n;i++) f[i]=s[n-i]=='V';
mul(b,f,t);
for (int i=0;i<t;i++) f[i]=0;
for (int i=1;i<=n;i++) if (s[i]=='V') c[i]=1;
for (int i=0;i<n;i++) f[i]=(P-4*(s[n-i]=='K'))%P;
mul(c,f,t);
int u=0;
for (int i=1;i<=n;i++)
{
bool flag=0;
for (int j=i;j<=n;j+=i)
if (a[n-j]+b[n-j]+c[n-j]) {flag=1;break;}
if (!flag) ans[++u]=i;
}
printf("%d\n",u);
for (int i=1;i<=u;i++) printf("%d ",ans[i]);printf("\n");
}
return 0;
//NOTICE LONG LONG!!!!!
}
F:容易想到拆点bfs,点数过多。注意到只要边还没消失就可以在上面反复横跳,每隔2s就能返回一次原来的点。于是只将每个点根据时刻奇偶性拆成两个点。拆完后重建一下图,根据所连点的奇偶性稍微调整一下边的起止时间。
这样可以在一个点逗留的时间段是连续(以2s为单位)的。考虑求出每个点最早什么时候能到,最晚什么时候走,这样就能得到答案了。
用边更新答案。考虑将所有已确定最早能何时经过的边扔进小根堆。每次取出堆顶对该边终点进行更新。然后根据该终点信息更新以其为起点的所有尚未确定最早经过时间的边。若该点最晚离开时间超过了边的出现时间,就确定其最早经过时间。容易发现这样得到的时间一定是最优的,因为要么是其出现时间,要么是当前最早经过的边的时间。否则不管。为保证复杂度需要提前将以某点为起点的边按出现时间从小到大排序。大约就是跑了个魔改dij。
另一种等价实现方法是一开始就把所有边扔进堆,具体见代码。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cassert>
using namespace std;
#define ll long long
#define N 500010
#define inf 1010000000
#define odd(i) ((i)+n)
#define even(i) (i)
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m,t,first[N<<1],last[N<<1],cur[N<<1];
struct data
{
int x,y,l,r;
bool operator <(const data&a) const
{
return l>a.l;
}
};
priority_queue<data> q;
vector<data> e[N<<1];
void addedge(int x,int y,int l,int r){if (l>r) return;t++;q.push((data){x,y,l,r});}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read(),m=read();
for (int i=1;i<=m;i++)
{
int x=read(),y=read(),l=read(),r=read();
addedge(odd(x),even(y),l+(l%2==0),r-(r&1));
addedge(even(x),odd(y),l+(l&1),r-(r%2==0));
addedge(odd(y),even(x),l+(l%2==0),r-(r&1));
addedge(even(y),odd(x),l+(l&1),r-(r%2==0));
}
for (int i=1;i<=n*2;i++) first[i]=inf,last[i]=-1;
first[1]=last[1]=0;
while (!q.empty())
{
data u=q.top();q.pop();
if (last[u.x]>=u.l)
{
if (first[u.x]>=u.r) continue;
u.l=max(first[u.x],u.l);
last[u.y]=max(last[u.y],u.r);
first[u.y]=min(first[u.y],u.l+1);
while (cur[u.y]<e[u.y].size()&&last[u.y]>=e[u.y][cur[u.y]].l)
{
data v=e[u.y][cur[u.y]++];
if (first[u.y]>=v.r) continue;
v.l=max(first[v.x],v.l);
last[v.y]=max(last[v.y],v.r);
first[v.y]=min(first[v.y],v.l+1);
q.push(v);
}
}
else e[u.x].push_back(u);
}
//for (int i=1;i<=n*2;i++) cout<<first[i]<<' '<<last[i]<<endl;
if (min(first[odd(n)],first[even(n)])>=inf) cout<<-1;
else cout<<min(first[odd(n)],first[even(n)]);
return 0;
//NOTICE LONG LONG!!!!!
}
Codeforces Round #423 Div. 1的更多相关文章
- Codeforces Round #423 (Div. 1, rated, based on VK Cup Finals)
Codeforces Round #423 (Div. 1, rated, based on VK Cup Finals) A.String Reconstruction B. High Load C ...
- Codeforces Round #423 (Div. 2)
codeforces 423 A. Restaurant Tables [水题] //注意,一个人选座位的顺序,先去单人桌,没有则去空的双人桌,再没有则去有一个人坐着的双人桌.读清题意. #inclu ...
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) E. DNA Evolution 树状数组
E. DNA Evolution 题目连接: http://codeforces.com/contest/828/problem/E Description Everyone knows that D ...
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) D. High Load 构造
D. High Load 题目连接: http://codeforces.com/contest/828/problem/D Description Arkady needs your help ag ...
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) C. String Reconstruction 并查集
C. String Reconstruction 题目连接: http://codeforces.com/contest/828/problem/C Description Ivan had stri ...
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) A,B,C
A.题目链接:http://codeforces.com/contest/828/problem/A 解题思路: 直接暴力模拟 #include<bits/stdc++.h> using ...
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem E (Codeforces 828E) - 分块
Everyone knows that DNA strands consist of nucleotides. There are four types of nucleotides: "A ...
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 828D) - 贪心
Arkady needs your help again! This time he decided to build his own high-speed Internet exchange poi ...
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem C (Codeforces 828C) - 链表 - 并查集
Ivan had string s consisting of small English letters. However, his friend Julia decided to make fun ...
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem A - B
Pronlem A In a small restaurant there are a tables for one person and b tables for two persons. It i ...
随机推荐
- .net core jwt
https://www.cnblogs.com/JacZhu/p/6837676.html
- flink1.7 checkpoint源码分析
初始化state类 //org.apache.flink.streaming.runtime.tasks.StreamTask#initializeState initializeState(); p ...
- 获取Oracle过程中的OUT SYS_REFCURSOR值
一个项目中的实例:获取Oracle过程中的返回SYS_REFCURSOR.注意:如果SYS_REFCURSOR为一个表或视图.可以通过表名%ROWTYPE获取每行数据,而不必另外定义type. 原过程 ...
- vue及Eelement使用过程中遇到的一些问题
在做项目的过程中,目前主要遇到了以下几个问题: 一.样式问题 1.样式中使用scoped的问题: 主要表现在从一个页面跳到另一个页面时,第二个页面的样式不能正确显示,通过刷新才能恢复页面的预定样式. ...
- 四、Input框改placeholder中字体的颜色
Input框改placeholder中字体的颜色 input::-webkit-input-placeholder { color: #ccc; font-size: 12px; }
- H5 video标签的属性
35-video标签 video标签的属性 src: 用于告诉video标签需要播放的视频地址 autoplay: 用于告诉video标签是否需要自动播放视频 controls: 用于告诉video标 ...
- Python-类的继承与派生
python中类的继承分为:单继承和多继承 class ParentClass1: #定义父类 pass class ParentClass2: #定义父类 pass class SubClass1( ...
- 1171: lfx捧杯稳啦!
escription Lfx在复习离散的时候突然想到了一个算法题,毕竟是lfx, 算法题如下: 他想知道这样的问题,先定义1~n中即是3的倍数,又是11的倍数的那些数的和sum, 他想知道sum有多少 ...
- 辨析element.offsetXxxx和element.style.xxxx
DOM操作时,经常使用element.style属性,没错,element.style是属性,和几个offsetXxxx属性一样,概念是一样的. 但是style有几个属性,这几个属性和offsetXx ...
- 为github添加ssh key
用git关联github上的远程仓库前需要先为github添加ssh key 一.检查本机是否生成ssh key 本地查找.ssh文件,其中id_rsa.pub中的内容就是ssh key 二.为git ...