周六的最后一战,感觉脑子确实有点混沌了一个C题好多细节没考虑好心态差点爆炸
最后还好20min速切了D稳了手排名,不然已经回到蓝名了
感觉最近打比赛老是犯一些很离谱的失误,题目老是想不清楚导致好几场没法在比赛时写掉Div2的E了
嘛说白了还是练得少了,多刷题解决一切问题的说
不难发现如果这两个点中有一个在角落上,那么只要堵住它临近的两个格子即可
否则如果有一个在边上,那么只要堵住它临近的三个格子即可
否则我们肯定可以用四个格子堵住其中任意一个
首先把所有翻转后对应的位置上的颜色比较一下,如果不一样就至少要花费一次操作
然后都执行完后看下如果k < 0 k < 0 则显然无解,否则要满足2 | k 2 | k 才能通过修改某对位置来满足要求
但是还要注意一个情况,当n n 为奇数时k k 为奇数也是合法的,因为我们可以把多余的操作全部扔在最中间的那个点上,刚开始没考虑到还WA了一发
思路很简单,但是我就是猪脑过载想不清楚,前前后后卡了快1h真是菜得飞起
一个很naive的想法就是我们尽量询问角落上的点,这样每次询问就能确定目标点在两条线段上
通过连续的两次询问可以很容易地把答案锁定在某个线段上,然后这样在第三次询问时我们可以询问线段的一个端点来确定位置了
说起来轻巧但是要注意很多Corner Cases
,比如考虑n , m n , m 的大小关系,相交的形态等等,具体看代码吧
早知道先写D题了,就是个模拟+STL的裸题
首先我们很容易想到旋转操作只会影响当前点、当前点的重儿子、当前点的父亲这三个点的信息
很显然可以直接用set
维护下每个点的重儿子信息,然后手玩一下转移过程别搞错细节就行
什么大缝合题,数论+树论+数据结构大综合了属于是,不过每个涉及得都很浅所以还是很好想的
首先很自然可以想到我们对于每个数x ( x > 1 ) x ( x > 1 ) ,连一条ϕ ( x ) → x ϕ ( x ) → x 的边,这样就形成了一颗树
然后询问就可以转化为求一个区间内所有点到它们的公共LCA的距离之和
很容易想到我们求出每个点的深度后就转化为区间求和和区间求LCA的问题了,但区间所有点的LCA乍一看感觉有点难处理的说
其实方法也很简单,我们找出区间内DFS序 最小和最大的点,则它们的LCA就是区间内所有点的LCA,这个画个图看一下还是很好理解的说
然后考虑修改,这个就是经典套路了,由于取ϕ ϕ 在log log 次后就会变成1 1 ,所以我们可以直接暴力搞,势能分析一下复杂度是对的
当然这个性质还给我们带来一个好处,由于树高是log log 级别的,所以我们不需要在写求LCA的算法了,直接暴力跳即可
总复杂度O ( n log A i ) O ( n log A i )
#include <cstdio>
#include <iostream>
#include <set>
#define RI register int
#define CI const int&
using namespace std;
const int N=100005 ,M=5000000 ;
int n,m,a[N],tp,l,r,pri[M+5 ],cnt,phi[M+5 ],seq[M+5 ],dfn[M+5 ],dep[M+5 ],idx;
bool vis[M+5 ]; set <int > s[M+5 ];
inline void init (CI n)
{
phi[1 ]=1 ; for (RI i=2 ,j;i<=n;++i)
{
if (!vis[i]) pri[++cnt]=i,phi[i]=i-1 ;
for (j=1 ;j<=cnt&&i*pri[j]<=n;++j)
if (vis[i*pri[j]]=1 ,i%pri[j]) phi[i*pri[j]]=phi[i]*(pri[j]-1 );
else { phi[i*pri[j]]=phi[i]*pri[j]; break ; }
}
}
inline void DFS (CI now=1 )
{
seq[dfn[now]=++idx]=now; dep[now]=dep[phi[now]]+1 ; for (int to:s[now]) DFS (to);
}
inline int getLCA (int x,int y)
{
if (dep[x]<dep[y]) swap (x,y);
while (dep[x]>dep[y]) x=phi[x];
if (x==y) return x;
while (phi[x]!=phi[y]) x=phi[x],y=phi[y];
return phi[x];
}
class Segment_Tree
{
private :
struct segment
{
long long sum; int mi,mx;
inline segment (const long long SUM=0 ,CI MI=1e9 ,CI MX=0 )
{
sum=SUM; mi=MI; mx=MX;
}
}node[N<<2 ];
#define S(now) node[now].sum
#define MI(now) node[now].mi
#define MX(now) node[now].mx
#define TN CI now=1,CI l=1,CI r=n
#define LS now<<1,l,mid
#define RS now<<1|1,mid+1,r
inline void pushup (CI now)
{
S (now)=S (now<<1 )+S (now<<1 |1 );
MI (now)=min (MI (now<<1 ),MI (now<<1 |1 ));
MX (now)=max (MX (now<<1 ),MX (now<<1 |1 ));
}
public :
inline void build (TN)
{
if (l==r) return (void )(node[now]=(segment){dep[a[l]],dfn[a[l]],dfn[a[l]]});
int mid=l+r>>1 ; build (LS); build (RS); pushup (now);
}
inline void modify (CI beg,CI end,TN)
{
if (beg<=l&&r<=end)
{
if (MX (now)==1 ) return ;
if (l==r) return (void )(a[l]=phi[a[l]],node[now]=(segment){dep[a[l]],dfn[a[l]],dfn[a[l]]});
}
int mid=l+r>>1 ; if (beg<=mid) modify (beg,end,LS); if (end>mid) modify (beg,end,RS); pushup (now);
}
inline long long getsum (CI beg,CI end,TN)
{
if (beg<=l&&r<=end) return S (now); int mid=l+r>>1 ; long long ret=0 ;
if (beg<=mid) ret+=getsum (beg,end,LS); if (end>mid) ret+=getsum (beg,end,RS); return ret;
}
inline int getmin (CI beg,CI end,TN)
{
if (beg<=l&&r<=end) return MI (now); int mid=l+r>>1 ,ret=1e9 ;
if (beg<=mid) ret=min (ret,getmin (beg,end,LS)); if (end>mid) ret=min (ret,getmin (beg,end,RS)); return ret;
}
inline int getmax (CI beg,CI end,TN)
{
if (beg<=l&&r<=end) return MX (now); int mid=l+r>>1 ,ret=0 ;
if (beg<=mid) ret=max (ret,getmax (beg,end,LS)); if (end>mid) ret=max (ret,getmax (beg,end,RS)); return ret;
}
#undef S
#undef MI
#undef MX
#undef TN
#undef LS
#undef RS
}SEG;
int main ()
{
RI i; for (scanf ("%d%d" ,&n,&m),init (M),i=1 ;i<=n;++i)
{
scanf ("%d" ,&a[i]); int tmp=a[i];
while (tmp>1 ) s[phi[tmp]].insert (tmp),tmp=phi[tmp];
}
for (DFS (),SEG.build (),i=1 ;i<=m;++i)
if (scanf ("%d%d%d" ,&tp,&l,&r),tp==1 ) SEG.modify (l,r); else
{
int lca=getLCA (seq[SEG.getmin (l,r)],seq[SEG.getmax (l,r)]);
printf ("%lld\n" ,SEG.getsum (l,r)-1LL *dep[lca]*(r-l+1 ));
}
return 0 ;
}
这场比赛是国人出的吧都是Li Hua的说,自从高中毕业后都以为再也不会见到了结果在CF上见到了
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
2018-04-12 Educational Codeforces Round 41 (Rated for Div. 2)(A~D)