传送门

\(A\)

咕咕

typedef long long ll;
int a1,a2,n,d;ll res;
int main(){
scanf("%d%d%d",&a1,&a2,&n);
d=a2-a1;
res=1ll*(a1+a1+1ll*(n-1)*d)*n>>1;
printf("%lld\n",res);
return 0;
}

\(B\)

不难发现答案要么是\(1\)要么是\(2\)

当且仅当\(k+1\)是个质数且范围内为\(k+1\)的倍数的数只有一个时,答案为\(1\)否则为\(2\)

据说\(n=2\)要特殊考虑,我是直接把\(n\leq 100\)的情况用暴力跑了

//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;
ll n,k;
inline bool ck(R ll x){fp(i,2,sqrt(x))if(x%i==0)return false;return true;}
int vis[105];
void solve(){
R int p=1;
vis[k+1]=1;
fp(res,1,2333){
fp(i,2,n+1)if(vis[i]==res)
fp(j,2,n+1)if(!vis[j])
if(__gcd(i,j)==1)vis[j]=res+1,++p;
if(p==n)return printf("%d\n",res),void();
}
}
int main(){
scanf("%lld%lld",&n,&k);
if(n<=100)return solve(),0;
puts(ck(k+1)&&(k+1)*2>n+1?"1":"2");
return 0;
}

\(C\)

二分+点分

二分最远的距离,同时强制点分中心必选,且以点分中心为根

那么一个点会被选,当且仅当它的子树中有点被选,或者它的子树中离他最远的点到他的距离\(=mid\)(即二分出的最远距离),如果选的点数小于等于\(k\)说明合法

因为点分的时候会删点,所以记得处理来自删点后的子树内的最远距离

ps:据说这题直接倍增就可以过了

//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;
struct eg{int v,nx;}e[N<<1];int head[N],tot;
inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
int sz[N],son[N],vis[N],ok[N],dis[N],las[N],rt,size;
int l,r,mid,ans,n,k,sum;bool fl;
inline int max(R int x,R int y){return x>y?x:y;}
void findrt(int u,int fa){
sz[u]=1,son[u]=0;
go(u)if(!vis[v]&&v!=fa)findrt(v,u),sz[u]+=sz[v],cmax(son[u],sz[v]);
cmax(son[u],size-sz[u]);
if(son[u]<son[rt])rt=u;
}
void did(int u,int fa){
ok[u]=0,dis[u]=las[u];
go(u)if(!vis[v]&&v!=fa)did(v,u),cmax(dis[u],dis[v]+1),ok[u]|=ok[v];
ok[u]|=(dis[u]>=mid),sum+=ok[u];
}
void solve(int u){
vis[u]=1,sum=0;
did(u,0);
if(!ok[u])ok[u]=1,++sum;
if(sum<=k)return fl=1,void();
R int t1=0,t2=0,to=0;
go(u)if(!vis[v]){
if(dis[v]+1>=t2)t1=t2,t2=dis[v]+1,to=v;
else cmax(t1,dis[v]+1);
}
if(las[u]>=t2)t1=t2,t2=las[u],to=0;
else cmax(t1,las[u]);
R int ss=size;
go(u)if(!vis[v]){
las[v]=v==to?t1+1:t2+1;
if(las[v]>mid)continue;
rt=0,size=sz[v]>sz[u]?size-sz[u]:sz[v],findrt(v,0),solve(rt);
if(fl)return;
}
}
int ck(){
memset(las,0,(n+1)<<2);
memset(vis,0,(n+1)<<2);
fl=0,son[0]=n+1;
size=n,rt=0,findrt(1,0),solve(rt);
return fl;
}
int main(){
scanf("%d%d",&n,&k);
for(R int i=1,u,v;i<n;++i)scanf("%d%d",&u,&v),add(u,v),add(v,u);
int l=1,r=n;
while(l<=r){
mid=(l+r)>>1;
ck()?(ans=mid,r=mid-1):l=mid+1;
}
printf("%d\n",ans);
return 0;
}

\(D\)

考虑跳儿子的过程,如果是跳到一个轻儿子,那么子树大小减半,所以跳轻儿子的总次数不会超过\(O(log n)\)次,所以我们只需要考虑优化跳重儿子的过程即可

对于每一个点,我们记录它的重儿子在它的儿子中标号是多少,那么跳重儿子的话只要计算它的重链和\(a_i\)的\(LCP\)即可,可以用二分+\(Hash\)求出

复杂度\(O(n\log^2 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;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R int x){
if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=5e5+5;
typedef unsigned long long ll;
vector<int>to[N];ll bas[N];
int n,q,m;
struct Bit{
ll c[N];
inline void upd(R int x,R ll y){y*=bas[x];for(;x<=N-5;x+=x&-x)c[x]+=y;}
inline ll query(R int x){R ll res=0;for(;x;x-=x&-x)res+=c[x];return res;}
inline ll query(R int l,R int r){return (query(r)-query(l-1))*bas[N-5-l];}
}T,G;
int sz[N],son[N],id[N],ed[N],dfn[N],rk[N],fa[N],a[N],deg[N],tim,rt;
void dfs1(int u){
sz[u]=1,sort(to[u].begin(),to[u].end());
R int c=0;
for(auto v:to[u]){
++c,dfs1(v),sz[u]+=sz[v];
if(sz[v]>sz[son[u]])son[u]=v,id[u]=c;
}
}
void dfs2(int u){
dfn[u]=++tim,rk[tim]=u,ed[u]=u;
if(!son[u])return T.upd(tim,-23333),void();
dfs2(son[u]),ed[u]=ed[son[u]],T.upd(dfn[u],id[u]);
for(auto v:to[u])if(v!=son[u])dfs2(v);
}
inline int min(R int x,R int y){return x<y?x:y;}
int LCP(R int li,R int ri,R int l,R int r){
int lp=1,rp=min(r-l+1,ri-li+1),ans=0,mid;
while(lp<=rp){
mid=(lp+rp)>>1;
T.query(li,li+mid-1)==G.query(l,l+mid-1)?(ans=mid,lp=mid+1):rp=mid-1;
}
return ans;
}
int solve(R int u,R int l,R int r){
R int li=dfn[u],ri=dfn[ed[u]];
while(233){
R int len=LCP(li,ri,l,r);
li+=len,l+=len;
u=rk[li];
if(l>r||deg[u]<a[l])return u;
u=to[u][a[l]-1],li=dfn[u],ri=dfn[ed[u]],++l;
if(l>r)return u;
}
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read(),q=read();
bas[0]=1;fp(i,1,N-5)bas[i]=bas[i-1]*19260817;
fp(i,1,n){
fa[i]=read();
if(fa[i])to[fa[i]].push_back(i),++deg[fa[i]];else rt=i;
}
dfs1(rt),dfs2(rt);
fp(i,1,m)a[i]=read(),G.upd(i,a[i]);
for(R int op,x,y,z;q;--q){
op=read(),x=read(),y=read();
if(op==2)G.upd(x,y-a[x]),a[x]=y;
else z=read(),print(solve(x,y,z));
}
return Ot(),0;
}

\(E\)

用原根预处理之后\(O(1)\)计算\(i^i\),同时直接暴力合并路径计算答案即可,具体细节看代码

然后是关于复杂度的问题,若\(u\)为其中一个点,且\(u\)到某个叶子的路径上的点分别为\(u,p_1,p_2,p_3,...,p_x\),那么路径\((u,u),(u,p_1),(u,p_2),...,(u,p_x)\)中,不同的\(\&\)值只有\(O(\log a_i)\)种,所以假设是一条链,且以其中一个叶子为根,那么每一次把子树里的所有形如\((v,i)\)的路径变成\((u,i)\)的复杂度是\(O(\log a_i)\),那么记\(d\)为叶子个数,在不合并路径的情况下复杂度为\(O(nd\log a_i)\)

对于路径的合并,两个叶子只会在它们的\(LCA\)处被合并一次,所以这部分复杂度为\(O(d^2\log^2 a_i)\),然后又因为路径总数是\(O(n^2)\),且根据不等式\(\min(a,b)\leq \sqrt{ab}\),所以\(\min(d^2\log^2 a_i,n^2)\leq O(nd\log a_i)\)

综上复杂度复杂度为\(O(nd\log a_i)\)

//quming
#include<bits/stdc++.h>
#define R register
#define pb push_back
#define fi first
#define se second
#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 P=786433,g=10;
inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
return res;
}
const int N=2e5+5;
struct eg{int v,nx;}e[N<<1];int head[N],tot;
inline void Add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
int ind[P],fpow[P];
inline void init(){
fpow[0]=1;
for(R int x=g,i=1;x!=1;x=mul(x,g),++i)ind[x]=i,fpow[i]=x;
}
inline int calc(R int x,R int y){
if(x%=P,!x)return 0;
return fpow[1ll*ind[x]*y%(P-1)];
}
typedef pair<int,int> pi;
int a[N],n,res;
vector<pi> dfs(int u,int fa){
vector<pi> now(1,pi(a[u],1));
go(u)if(v!=fa){
vector<pi> to=dfs(v,u),tt;
for(auto &x:to)x.fi&=a[u];
pi p(0,0);
for(auto x:to)if(p.fi!=x.fi){
if(p.fi)tt.pb(p);
p=x;
}else p.se+=x.se;
if(p.fi)tt.pb(p);
for(const auto &x:now)for(const auto &y:tt)
upd(res,1ll*calc(x.fi&y.fi,x.fi&y.fi)*x.se*y.se%P);
now.insert(now.end(),tt.begin(),tt.end());
}
return now;
}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d",&n),init();
fp(i,1,n)scanf("%d",&a[i]),upd(res,calc(a[i],a[i]));
for(R int i=1,u,v;i<n;++i)scanf("%d%d",&u,&v),Add(u,v),Add(v,u);
dfs(1,0);
printf("%d\n",res);
return 0;
}

\(F\)

先考虑一个暴力,把\(S\)中每一个数的倍数都存在一个\(bitset\)里,记为\(A\),那么答案就是\(A\&(A>>1)\&(A>>2)\)

然而这样显然会\(T\),那么我们考虑设阈值,对于\(x\)大于阈值的部分,我们还是直接枚举倍数并记到\(A\)里,否则我们找出\(x\)的倍数的循环节的情况,然后在循环节上对\(A\)处理就行了

顺便记得找循环节的时候千万别取模……\(\%\)的常数非常大甚至会\(T\)……

//quming
#include<bits/stdc++.h>
#define R register
#define pc(x) __builtin_popcountll(x)
#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 unsigned long long ll;
const int N=(1000000000>>6)+233;
struct Bit{
ll p[N];
inline void ins(R int x){p[x>>6]|=(1ull<<(x&63));}
}A;
ll b[64*64+5];int n,S,mx,res;
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d%d",&n,&S),mx=(n>>6);
for(R int x;S;--S){
scanf("%d",&x);
if(x==1)return printf("%d\n",n-2),0;
if(x<=64){
fp(i,0,x-1)b[i]=0;
for(R int i=0;i<(x<<6);i+=x)b[i>>6]|=(1ull<<(i&63));
for(R int i=0,j=0;i<=mx;++i){
A.p[i]|=b[j];
if(++j==x)j=0;
}
}else for(R int i=x;i<=n;i+=x)A.ins(i);
}
A.p[(n+1)>>6]&=(1ull<<((n+1)&63))-1;
fp(i,0,mx)res+=pc(A.p[i]&(A.p[i]>>1)&(A.p[i]>>2));
fp(i,1,mx){
R ll tmp=(A.p[i-1]>>62)|((A.p[i]&3)<<2);
res+=pc(tmp&(tmp>>1)&(tmp>>2));
}
printf("%d\n",res);
return 0;
}

Comet OJ - Contest #9 & X Round 3题解的更多相关文章

  1. [Comet OJ - Contest #9 & X Round 3] Namid[A]me

    传送门 一开始读错题了,以为是\(\sum_{1\leq u\leq v\leq n}f(u,v)\),还疑惑这题这么简单怎么没人做( 实际上是\(\sum_{1\leq u\leq v\leq n} ...

  2. Comet OJ - Contest #9 & X Round 3 【XR-3】核心城市 【树的理解】

    一.题目 [XR-3]核心城市 二.分析 题意就是在树中确定$K$个点,满足剩下的$N-K$个点中到这$K$个点的最大距离尽可能小. 理解上肯定是确定一个根,这个根是这个图的中心. 可以通过根据结点的 ...

  3. Comet OJ - Contest #2 简要题解

    Comet OJ - Contest #2 简要题解 cometoj A 模拟,复杂度是对数级的. code B 易知\(p\in[l,r]\),且最终的利润关于\(p\)的表达式为\(\frac{( ...

  4. Comet OJ - Contest #2简要题解

    Comet OJ - Contest #2简要题解 前言: 我没有小裙子,我太菜了. A 因自过去而至的残响起舞 https://www.cometoj.com/contest/37/problem/ ...

  5. Comet OJ - Contest #11 题解&赛后总结

    Solution of Comet OJ - Contest #11 A.eon -Problem designed by Starria- 在模 10 意义下,答案变为最大数的最低位(即原数数位的最 ...

  6. Comet OJ - Contest #5

    Comet OJ - Contest #5 总有一天,我会拿掉给\(dyj\)的小裙子的. A 显然 \(ans = min(cnt_1/3,cnt_4/2,cnt5)\) B 我们可以感性理解一下, ...

  7. Comet OJ - Contest #4--前缀和

    原题:Comet OJ - Contest #4-B https://www.cometoj.com/contest/39/problem/B?problem_id=1577传送门 一开始就想着暴力打 ...

  8. Comet OJ - Contest #8

    Comet OJ - Contest #8 传送门 A.杀手皇后 签到. Code #include <bits/stdc++.h> using namespace std; typede ...

  9. Comet OJ - Contest #13-C2

    Comet OJ - Contest #13-C2 C2-佛御石之钵 -不碎的意志-」(困难版) 又是一道并查集.最近做过的并查集的题貌似蛮多的. 思路 首先考虑,每次处理矩形只考虑从0变成1的点.这 ...

随机推荐

  1. 8 search中的timeout参数

    默认的search,是没有时间限制的.比如,一个search,可能要10分钟才能搜完,那么,es就会等10分钟,直到结果出来.   然而,在某些场景下,客户是等不了10分钟的.比如,电商网站,客户宁可 ...

  2. windows下pyinstaller打包踩坑记录

    示例: 需要打包的是 ReadConfig.py 文件,同文件夹下调用了Interface.py文件,ui文件夹下调用了 Ui_config.py和Ui_Error.py文件,Interface.py ...

  3. mkimage命令

    # mkimage Usage: mkimage -l image -l ==> list image header information mkimage [-x] -A arch -O os ...

  4. Mysql修改binlog日志过期时间

    1.临时生效 # 查看默认设置的过期时间 show variables like "%expire_logs%"; # 设置保留15天 set global expire_logs ...

  5. ICS2019汇编实验在Linux下使用GDB调试程序

  6. CentOS 7 修改时区例如上海时区

    Linux 系统(我特指发行版, 没说内核) 下大部分软件的风格就是不会仔细去考虑向后 的兼容性, 比如你上个版本能用这种程序配置, 没准到了下一个版本, 该程序已经不见了. 比如 sysvinit ...

  7. IDEA实用教程(八)—— 创建JavaWeb项目

    七. 创建JavaWeb项目 创建工程 1) 第一步 2) 第二步 3) 第三步 如果要修改JavaEE版本,请根据下图所示进行修改 4) 第四步 2. 发布工程 1) 第一步 2) 第二步 3) 第 ...

  8. 基于Java+Selenium的WebUI自动化测试框架(十二)-----读取Excel文件(POI)(2)

    上一篇我们讲了怎么利用Java的反射机制,将Excel的读取到的数据,赋值给我们构造函数中定义的变量. 接下来就简单了,我们将实际实现这个读取的简单过程.来看下面一段代码. private stati ...

  9. 如何解决WinForm中TableLayout控件闪烁的问题

    public FormReg() { InitializeComponent(); typeof(TableLayoutPanel) .GetProperty("DoubleBuffered ...

  10. [转] ubuntu16.04添加系统 service, 并设置开机自动启动

    转:https://www.jianshu.com/p/1958878646bd 1. 创建pfly.service文件 2.  执行 systemctl daemon-reload 3. 执行 sy ...