Comet OJ - Contest #9 & X Round 3题解

Portal

\(A\)

Cuckoo

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\)

The answer is not difficult to find either \ (1 \) either \ (2 \)

If and only if \ (k + 1 \) is the prime number and the scope of \ (k + 1 \) only a multiple of the number, the answer is \ (1 \) otherwise \ (2 \)

It is said that \ (n = 2 \) to special consideration, I was directly \ (n \ leq 100 \) in the case of violence ran

//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\)

Binary dotted +

Two points furthest distance, while enforcing mandatory dotted center, and the center of the root dotted

Then a point is selected, if and only if it is selected subtree bit, or its subtree point farthest away from him to his distance \ (MID = \) (i.e. the maximum distance of two separated ), if the selected points or less \ (K \) described legitimate

Because time will be deleted dotted point, so remember to handle the most distance in the sub-tree after the deletion from the point

ps: It is said that this problem can be passed directly to the multiplier

//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\)

Consider the process of jumping son, if it is a jump to light his son, then the sub-tree size is halved, so the total number of light-hop son will not exceed \ (O (log n) \ ) times, so we only need to consider re-optimization jump son of the process can be

For each point, we recorded its heavy son of its sons label is how much, then skip the heavy words of his son as long as the calculation of its heavy chain and \ (a_i \) is \ (LCP \) can be used binary + \ (Hash \) obtained

Complexity \ (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\)

After pretreatment with the primitive root \ (O (1) \) is calculated \ (I ^ I \) , while direct violence combined to path computation answer, details see Code

Then the question of complexity, if \ (u \) is one of the points, and \ (u \) onto a path leaves the points were \ (u, p_1, p_2, p_3, ..., p_x \) , then the path \ ((u, u), (u, p_1), (u, p_2), ..., (u, p_x) \) , different \ (\ & \) values only \ (O (\ log a_i) \ ) species, it is assumed that one strand, and to which a leaf is the root, then each of all the sub-tree of the form \ ((v, i) \ ) path becomes \ ((u, i) \) complexity is \ (O (\ log a_i) \) , then the note \ (D \) is the number of leaves, without merging path complexity \ (O (nd \ log a_i) \)

For the path merge, only two leaves at their \ (the LCA \) are combined at once, so this part complexity \ (O (D ^ 2 \ ^ 2 log a_i) \) , but it seems difficult to card the upper bound (at least I did not find to make it a data card upper bound)

To sum up the complexity is not a problem

//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\)

Consider a violence, the \ (S \) multiples of each number there is a \ (bitset \) , the record for the \ (A \) , then the answer is \ (A \ & (A >> 1) \ & (A >> 2) \)

However, this will obviously \ (T \) , then we consider the set threshold for \ (x \) portion is greater than the threshold, we direct enumeration multiples and credited to \ (A \) , otherwise we find \ (x \) of a multiple section loop, then the loop section of the \ (a \) process on the line

Incidentally, remember to find the time do not cycle section modulus ...... \ (\% \) is constant is very large even \ (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;
}

Guess you like

Origin www.cnblogs.com/yuanquming/p/11421087.html