传送门

\(A\)

咕咕

const int N=105;
char s[N],t[N];int n;
inline bool eq(R int k){fp(i,1,k)if(s[n-k+i]!=t[i])return false;return true;}
int main(){
scanf("%d%s%s",&n,s+1,t+1);
fd(k,n,0)if(eq(k))return printf("%d\n",(n<<1)-k),0;
return 233;
}

\(B\)

把\(x\)放在最中间,然后在它左边放一个比它大的数,右边放两个比它小的数就行了

具体证明在\(D\)题里

const int N=5e5+5;
int vis[N],st[N],a[N],top,n,x;
int main(){
scanf("%d%d",&n,&x);
if(x==1||x==(n<<1)-1)return puts("No"),0;
puts("Yes");
if(x!=2){
a[n]=x,a[n-1]=x+1,a[n+1]=x-1,a[n+2]=x-2;
vis[x]=vis[x+1]=vis[x-1]=vis[x-2]=1;
}else{
a[n]=x,a[n-1]=x-1,a[n+1]=x+1,a[n+2]=x+2;
vis[x]=vis[x-1]=vis[x+1]=vis[x+2]=1;
}
fp(i,1,(n<<1)-1)if(!vis[i])st[++top]=i;
fp(i,1,n-2)a[i]=st[top--];
fp(i,n+3,(n<<1)-1)a[i]=st[top--];
fp(i,1,(n<<1)-1)printf("%d\n",a[i]);
return 0;
}

\(C\)

首先,假设操作的数为\(i\),左右分别为\(x,y\),那么操作之后的期望位置为\((2x-i+2y-i)/2=x+y-i\)

设\(a_i\)为原数组的差分数组,那么一次操作之后等价于交换\(a_i,a_{i+1}\)

因为\(m\)次操作等价于一个轮换,所以把轮换中的每个循环找出来就行了

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
typedef long long ll;
const int N=1e5+5;
int a[N],id[N],sz[N],bl[N],to[N],nid[N],n,m;ll sum[N],k;
vector<int>st[N];
inline void swap(R int &x,R int &y){R int t=x;x=y,y=t;}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d",&n);
fp(i,1,n)scanf("%d",&a[i]);
fd(i,n,1)a[i]-=a[i-1],id[i]=i;
scanf("%d%lld",&m,&k);
for(R int i=1,x;i<=m;++i)scanf("%d",&x),swap(id[x],id[x+1]);
fp(i,1,n)to[id[i]]=i;
fp(i,1,n)if(!bl[i]){
bl[i]=i,++sz[i];
for(R int j=to[i];j!=i;j=to[j])bl[j]=i,++sz[i];
st[i].resize(sz[i]),st[i][0]=i,nid[i]=0;
for(R int j=to[i],c=1;j!=i;j=to[j],++c)st[i][c]=j,nid[j]=c;
}
fp(i,1,n)sum[st[bl[i]][(k+nid[i])%sz[bl[i]]]]=a[i];
fp(i,1,n)sum[i]+=sum[i-1];
fp(i,1,n)printf("%lld\n",sum[i]);
return 0;
}

\(D\)

首先二分答案,把大于等于\(mid\)的记为\(1\),其余的记为\(0\),那么就转化为判断顶上是\(0/1\)

先判断两种特殊情况,\(101010.....101\),顶上必定为\(1\),\(0101010....010\),顶上必定为\(0\)

为了方便把边界去掉,也就是说看成一个\(n\)行\(2n-1\)列的网格,最终查询第一行第\(n\)列的值

发现有如下性质

\(1.\)假设有一段极长的全为\(0/1\)的段,记为\([l,r]\),且\(l\neq r\),那么上面所有行中\([l,r]\)这几列将一直为\(0/1\)

\(2.\)假设有一段极长的\(0/1\)相间的段,记为\([l,r]\),且\(l\neq r\),那么最终会在上面的某一行形成以\(p\)为分界的两个区间\([l,p]\)和\([p+1,r]\),且两个区间都满足性质\(1\)(\(p\)的位置取决于这个区间的奇偶性)

综上,最终所有区间都会形成满足性质\(1\)的区间,只要\(O(n)\)求出所有区间的右端点,即可查询最终第一行第\(n\)列的值为\(0/1\)了

综上,总复杂度为\(O(n\log n)\)

ps:这里也就可以说明\(B\)的正确性了,只要找到一组使得\(mid=x\)时顶上为\(1\)且\(mid=x+1\)时顶上为\(0\)的解即可

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int N=5e5+5;
int a[N],b[N],st[N],col[N],n,t,l,r,mid,ans;
bool ck(){
fp(i,1,n)b[i]=a[i]>=mid;
R int top=0;bool fl1=1,fl2=1;
fp(i,1,n)fl1&=(b[i]==(i&1)),fl2&=(b[i]!=(i&1));
if(fl1)return true;if(fl2)return false;
for(R int l=1,r=2;r<=n;l=r++){
if(b[r]==b[l]){
while(r+1<=n&&b[r+1]==b[l])++r;
st[++top]=r,col[top]=b[l];
}else{
while(r+1<=n&&((r+1-l)&1)==(b[r+1]^b[l]))++r;
if((r-l+1)&1)st[++top]=r,col[top]=b[l];
else st[++top]=(l+r)>>1,col[top]=b[l],st[++top]=r,col[top]=b[r];
}
}
assert(top);
fp(i,1,top)if(st[i-1]<=t&&st[i]>=t)return col[i];
}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d",&n),t=n,n=(n<<1)-1;
fp(i,1,n)scanf("%d",&a[i]);
l=2,r=n-1;
while(l<=r){
mid=(l+r)>>1;
ck()?(ans=mid,l=mid+1):r=mid-1;
}
printf("%d\n",ans);
return 0;
}

\(E\)

为什么我什么题都不会啊

首先,我们发现同一列的三个数永远在同一列,且只会有正序和逆序两种情况,不妨分别记为\(i\)和\(-i\)

其次,一次操作可以看成是把三个数取反,并交换间隔的两个数

那么我们把操作拆开来,一个是交换相隔的两个数(交换的过程中包括取反),一个是把某个数取反

交换相隔的数,我们显然可以把奇偶分开考虑

那么现在问题转化成给定一个排列,要把它变为有序,每一次可以交换相邻的两个数,求每一个数要交换多少次

这个可以贪心,即先把最大的搞到最后,再把次大的搞到最后……

那么每个数取反的次数,只要根据原来的情况和要交换的情况判断一下就好了

最后回到原问题,我们发现奇数的一次交换对应于偶数的一次取反

所以奇数的交换总次数要与偶数的取反总次数奇偶性相等

同理偶数的交换总次数也要和奇数的交换总次数相等

总复杂度\(O(n\log n)\)

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int N=1e5+5;
int n,a[N],b[N],c[N],f[N],g[N],id[N];
struct BIT{
int c[N];
inline void clr(){memset(c,0,(n+1)<<2);}
inline void upd(R int x,R int y){for(;x<=n;x+=x&-x)c[x]+=y;}
inline int query(R int x){R int res=0;for(;x;x-=x&-x)res+=c[x];return res;}
}t1,t2;
bool ck(){
fp(i,1,n){
id[i]=(a[i]-1)/3+1;
if((i&1)!=(id[i]&1))return false;
R int x=(id[i]-1)*3+1,y=(id[i]-1)*3+2,z=(id[i]-1)*3+3;
if(a[i]==x&&b[i]==y&&c[i]==z){g[i]=(n<<1);continue;}
if(a[i]==z&&b[i]==y&&c[i]==x){g[i]=(n<<1|1);continue;}
return false;
}
return true;
}
int main(){
scanf("%d",&n);
fp(i,1,n)scanf("%d",&a[i]);
fp(i,1,n)scanf("%d",&b[i]);
fp(i,1,n)scanf("%d",&c[i]);
if(!ck())return puts("No"),0;
for(R int i=1;i<=n;i+=2)t1.upd(i,1);
for(R int i=n-(n&1^1);i>0;i-=2){
f[i]=t1.query(n)-t1.query(id[i])+t2.query(id[i]-1);
t1.upd(id[i],-1),t2.upd(id[i],1);
}
t1.clr(),t2.clr();
for(R int i=2;i<=n;i+=2)t1.upd(i,1);
for(R int i=n-(n&1);i>0;i-=2){
f[i]=t1.query(n)-t1.query(id[i])+t2.query(id[i]-1);
t1.upd(id[i],-1),t2.upd(id[i],1);
}
fp(i,1,n)g[i]=(g[i]-f[i])&1;
R int s=0,t=0;
for(R int i=1;i<=n;i+=2)s+=g[i];
for(R int i=2;i<=n;i+=2)t+=f[i];
t>>=1;
if((s&1)!=(t&1))return puts("No"),0;
s=0,t=0;
for(R int i=2;i<=n;i+=2)s+=g[i];
for(R int i=1;i<=n;i+=2)t+=f[i];
t>>=1;
if((s&1)!=(t&1))return puts("No"),0;
return puts("Yes"),0;
}

\(F\)

又做不来系列

先把一个黑点\((x,y)\)转化成\(x\)到\(y\)的一条有向边

又因为两个弱连通块(把有向边视作无向边之后的连通块)之间互不影响,所以我们单独考虑一个弱连通块

首先,如果存在自环,那么这个点所在的整个弱连通块中所有边都会相连(包括自环)

这是因为所有和这个点存在单向边的点都会变成双向边,有双向边后又会形成自环,一直重复之后会把所有边都连起来

判断自环的话,我们把原图进行\(3\)染色,那么会有三种情况

  • 不存在合法染色方案,那么必定有自环,答案就是该弱连通块的\(size\times size\)

  • 存在合法染色方案,但是有一种颜色没有出现,那么无法连上任何一条边

  • 否则的话,若\(color[u]+1\equiv color[v]\pmod{3}\),则\((u,v)\)之间必有一条边,设\(c[i]\)表示颜色为\(i\)的数的出现次数,则答案为\(c[0]\times c[1]+c[1]\times c[2]+c[2]\times c[0]\)

证明的话建议感性理解一下

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
typedef long long ll;
const int N=1e5+5;
struct eg{int v,nx,w;}e[N<<1];int head[N],tot;
inline void add(R int u,R int v,R int w){e[++tot]={v,head[u],w},head[u]=tot;}
int dis[N],c[3],eg,sz,fl,n,m;ll ans;
void dfs(int u,int w){
dis[u]=w,++c[w],++sz;
go(u){
++eg;
if(dis[v]==-1)dfs(v,(dis[u]+e[i].w)%3);
else if(dis[v]!=(dis[u]+e[i].w)%3)fl=0;
}
}
int main(){
scanf("%d%d",&n,&m);
for(R int i=1,u,v;i<=m;++i)scanf("%d%d",&u,&v),add(u,v,1),add(v,u,2);
memset(dis,-1,(n+1)<<2);
fp(i,1,n)if(dis[i]==-1){
eg=sz=c[0]=c[1]=c[2]=0,fl=1;
dfs(i,0);eg>>=1;
if(fl)ans+=(!c[0]||!c[1]||!c[2]?eg:1ll*c[0]*c[1]+1ll*c[1]*c[2]+1ll*c[2]*c[0]);
else ans+=1ll*sz*sz;
}
printf("%lld\n",ans);
return 0;
}

AtCoder Grand Contest 006 题解的更多相关文章

  1. AtCoder Grand Contest 006

    AtCoder Grand Contest 006 吐槽 这套题要改个名字,叫神仙结论题大赛 A - Prefix and Suffix 翻译 给定两个串,求满足前缀是\(S\),后缀是\(T\),并 ...

  2. AtCoder Grand Contest 006 C:Rabbit Exercise

    题目传送门:https://agc006.contest.atcoder.jp/tasks/agc006_c 题目翻译 数轴上有\(N\)只兔子,从\(1\)到\(N\)编号,每只兔子初始位置是\(x ...

  3. AtCoder Grand Contest 017 题解

    A - Biscuits 题目: 给出 \(n\) 个物品,每个物品有一个权值. 问有多少种选取方式使得物品权值之和 \(\bmod\space 2\) 为 \(p\). \(n \leq 50\) ...

  4. Atcoder Grand Contest 054 题解

    那天晚上由于毕业晚会与同学吃饭喝酒没打 AGC,第二天稍微补了下题,目前补到了 E,显然 AGC 的 F 对于我来说都是不可做题就没补了(bushi A 简单题,不难发现如果我们通过三次及以上的操作将 ...

  5. AtCoder Grand Contest 030题解

    第一次套刷AtCoder 体验良好 传送门 Poisonous Cookies cout<<b+min(c,a+b+); Tree Burning 难度跨度有点大啊 可以证明当第一次转向之 ...

  6. AtCoder Grand Contest 006 (AGC006) C - Rabbit Exercise 概率期望

    原文链接https://www.cnblogs.com/zhouzhendong/p/AGC006C.html 题目传送门 - AGC006C 题意 有 $n$ 个兔子,从 $1$ 到 $n$ 编号, ...

  7. AtCoder Grand Contest 031题解

    题面 传送门 题解 比赛的之后做完\(AB\)就开始发呆了--简直菜的一笔啊-- \(A - Colorful\ Subsequence\) 如果第\(i\)个字母选,那么它前面任意一个别的字母的选择 ...

  8. AtCoder Grand Contest 039 题解

    传送门 \(A\) 首先只有一串的情况下,遇到相同的肯定是改后面那一个最优,然后两串的话可能要分奇偶讨论一下 //quming #include<bits/stdc++.h> #defin ...

  9. AtCoder Grand Contest 017题解

    传送门 \(A\) 直接转移就是了 typedef long long ll; const int N=55; ll f[N][2];int a[N],n,p; int main(){ scanf(& ...

随机推荐

  1. 一步一步手写GIS开源项目-(2)地图平移缩放实现

    系列文章目录 一步一步手写GIS开源项目-(1)500行代码实现基础GIS展示功能 一步一步手写GIS开源项目-(2)地图平移缩放实现 项目github地址:https://github.com/Hu ...

  2. C# vb .net实现移除透明度效果

    在.net中,如何简单快捷地实现Photoshop滤镜组中的移除透明度效果呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 ...

  3. c#的一些书写技巧

    从非创建线程访问线程资源 Invoke(new Action<int>((o)=> {  textBox1.Text = (Convert.ToInt32(textBox1.Text ...

  4. 【kubernetes】通过rancher2部署k8s

    1. K8S相关介绍 十分钟带你理解Kubernetes核心概念 2. 部署rancher # 更新操作系统软件包 yum update -y # 删除历史容器及数据 docker rm -f $(d ...

  5. UCOSIII消息队列

    任务间消息传递2种途径 全局变量 发布消息 主结构体 typedef struct os_q OS_Q; struct os_q { /* Message Queue */ OS_OBJ_TYPE T ...

  6. 0001-代码仓库-mvn

    暂缺 基本介绍 web管理 ifsvnadmin

  7. 【MySQL】SQL语句基础

    一.操作数据库 1.1 创建数据库 1.2 查看数据库 1.3 修改数据库 1.4 删除数据库 1.5 选择数据库 二.操作表 2.1 创建表 2.2 查看表 2.3 修改表 2.4 删除表 三.操作 ...

  8. 安装sqlite3

    说明 当前操作在root用户下执行 1.安装编译工具 yum -y groupinstall "Development tools" yum -y install zlib-dev ...

  9. php实现人员权限管理(管理员界面)

    控制人员权限用的最多的应该是OA办公自动化系统和像ERP,CRM,CMS这样的管理系统,就是通过控制用户的权限来控制其拥有的角色和功能,比如管理员可以拥有所有权限和功能,前台只能拥有登记和通报信息等. ...

  10. sql写法,子节点名称拼接上级节点名称

    with T(id,[name],pid) as(select 1,N'中国',-1 union allselect 2,N'山东',1 union allselect 3,N'济南',2 union ...