CodefChef September Challenge 2019 题解

Portal

\(CHEFK1\)

First of all and even a ring from the ring, leaving each time you press \ (n \) th consecutive on it

//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,m,res;int T;
int main(){
    for(scanf("%d",&T);T;--T){
        scanf("%lld%lld",&n,&m);
        if(m<n-1||m>(n*(n+1)>>1)){puts("-1");continue;}
        if(n==1){puts(m?"1":"0");continue;}
        if(n==2){puts(m==1?"1":"2");continue;}
        if(m<=n+n){puts(m>n+1?"3":"2");continue;}
        m-=n+n,res=3,res+=(m/n)<<1,m%=n;
        if(m)m<=(n>>1)?++res:res+=2;
        printf("%lld\n",res);
    }
    return 0;
}

\(FUZZYLIN\)

First, a range legitimate if and only if the interval \ (\ gcd \) is \ (k \) factor, can be used to prove theorems Shu Pei

For a fixed left point, right point at the right of different process \ (\ gcd \) number only \ (O (\ log n) \) months, then we enumerate the left point, and each time to find the next half the right to a different point on the line, and finally \ (O (n \ log n ) \) pre-answer

Overall 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;
typedef long long ll;
const int N=1e6+5;
ll cnt[N],s[N];int st[N][25],a[N],Log[N],n,q;
int gcd(R int x,R int y){return !y?x:gcd(y,x%y);}
inline int Gcd(R int l,R int r){
    R int k=Log[r-l+1];
    return gcd(st[l][k],st[r-(1<<k)+1][k]);
}
void find(R int pos){
    R int l,r,mid,ans,las=pos,p;
    while(las<=n){
        l=las,r=n,ans=las,p=Gcd(pos,las);
        if(p==1)return cnt[1]+=n-las+1,void();
        while(l<=r){
            mid=(l+r)>>1;
            Gcd(pos,mid)==p?(ans=mid,l=mid+1):r=mid-1;
        }
        if(p<=1e6)cnt[p]+=ans-las+1;
        las=ans+1;
    }
}
int main(){
//  freopen("testdata.in","r",stdin);
    scanf("%d",&n);
    fp(i,1,n)scanf("%d",&a[i]),st[i][0]=a[i];
    fp(i,2,n)Log[i]=Log[i>>1]+1;
    for(R int j=1;n>>j;++j)fp(i,1,n-(1<<j)+1)
        st[i][j]=gcd(st[i][j-1],st[i+(1<<(j-1))][j-1]);
    fp(i,1,n)find(i);
    for(R int i=1;i<=1e6;++i)for(R int j=i;j<=1e6;j+=i)s[j]+=cnt[i];
    scanf("%d",&q);
    for(R int i=1,x;i<=q;++i)scanf("%d",&x),printf("%lld\n",s[x]);
    return 0;
}

\ (LAPD \)

May first \ (- c \ - a, ) into after \ (AX ^ 2 ^ 2 + CY + 2bxy> 0 \) , and that this condition is not satisfied if and only if \ (x, y \) opposite sign, then can be turned into \ (ax ^ 2-2bxy + cy ^ 2> 0 \)

Then left that requires the minimum function, can \ (X \) seeking a partial derivative, the \ (2AX-2BY = 0 \) , i.e. \ (y = {a \ over b} x \)

After bring simplification, available \ (AC> b ^ 2 \) , so that's the number we want to count the number of

We enumerate \ (b \) , then divided into three cases, if \ (a, c> x \ ) is certainly legitimate, otherwise \ (a, c \) , only a \ (\ Leq b \) , then we enumeration that less \ (B \) is the number, and calculates a lower bound to the number of further

//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 P=1e9+7;
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=2.5e7+5;
int s[N],T,a,b,c,res,p,sum,n,m,x;
inline int min(R int x,R int y){return x<y?x:y;}
inline int max(R int x,R int y){return x>y?x:y;}
int main(){
//  freopen("testdata.in","r",stdin);
    for(scanf("%d",&T);T;--T){
        scanf("%d%d%d",&a,&b,&c),res=0,--a,--c;
        m=b*b;
        fp(i,1,b){
            fp(j,1,min(i,a)){
                x=i*i/j+1;
                if(x<=c)upd(res,c-x+1);
            }
            fp(k,1,min(i,c)){
                x=i*i/k+1;
                if(x<=a)upd(res,a-x+1);
            }
            if(a>i&&c>i)upd(res,mul(a-i,c-i));
        }
        printf("%d\n",res);
    }
    return 0;
}

\(EXPGCD\)

We enumerate \ (\ I GCD = \) , and then consider how to calculate \ (n-\) the number of selected \ (K \) the number of allowed \ (\ GCD \) of \ (I \)

First, \ (= for n-[I \ X Times, I \ Times (X +. 1) -1] \) , the answer is the same, then we can calculate a prefix and then treated with

Secondly, let \ (P = \ left \ {n-lfloor \ over K} \ right \ rfloor \) , then the problem can be transformed into the \ ([1, p] \ ) Selection \ (K \) number so \ (\ GCD \) of \ (1 \) , and \ (\ gcd = 1 \) this condition can be \ (\ MU \) receiving repellent off

Then we can first \ (O (n \ log n ) \) preconditioning the \ (g [i] \) represents the \ ([1, i] \ ) is selected in \ (K \) the number of allowed \ (\ GCD \) of \ (1 \) scheme, and then use the \ (G \) is calculated \ (\ GCD \) of \ (I \) corresponding to a desired position for each time contribution, i.e., the last prefix and a lower can

Specific details can reference code

//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 P=1e9+7;
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=5e5+5;
bitset<N>vis;int fac[N],ifac[N],g[N],ans[N],p[N],mu[N],sum[N];
int n,m,k,q;
inline int A(R int n,R int m){return mul(fac[n],ifac[n-m]);}
void init(int n){
    fac[0]=ifac[0]=1;fp(i,1,n)fac[i]=mul(fac[i-1],i);
    ifac[n]=ksm(fac[n],P-2);fd(i,n-1,1)ifac[i]=mul(ifac[i+1],i+1);
    mu[1]=1;
    fp(i,2,n){
        if(!vis[i])p[++m]=i,mu[i]=-1;
        for(R int j=1;j<=m&&i*p[j]<=n;++j){
            vis[i*p[j]]=1;
            if(i%p[j]==0)break;
            mu[i*p[j]]=-mu[i];
        }
    }
    fp(i,1,n)upd(mu[i],P);
    fp(i,1,n/k)if(mu[i]){
        for(R int j=i*k,c=k,s;j<=n;j+=i,++c)
            s=mul(A(c,k),mu[i]),upd(g[j],s),upd(g[j+i],P-s);
    }
    fp(i,1,n)upd(g[i],g[i-1]);
//  fp(i,1,10)printf("%d %d\n",i,g[i]);
    fp(i,1,n/k){
        for(R int j=i*k,c=k,s;j<=n;j+=i,++c)
            s=mul(g[c],i),upd(sum[j],s),upd(sum[j+i],P-s);
    }
    fp(i,1,n)upd(sum[i],sum[i-1]);
//  fp(i,1,10)printf("%d %d\n",i,sum[i]);
    fp(i,k,n)sum[i]=mul(sum[i],mul(fac[i-k],ifac[i]));
}
int main(){
//  freopen("testdata.in","r",stdin);
    scanf("%d%d",&q,&k);
    init(2e5);
    while(q--)scanf("%d",&n),printf("%d\n",sum[n]);
    return 0;
}

\ (DOOFST \)

First, we found that if there is no edge between two points, then they must have been in the same collection, and if the two sides have points on their behalf at least once in different collections, so the original problem has a solution if and only if each communication block its complement are completely FIG view, and if each of the communicating block diagram shrunk complement a point corresponding to the original image must be a complete graph

So we first consider if the deal is complete view of how this can be every time the size of a \ (size \) connectivity blocks were divided into two, then two small connected blocks thrown in two different sets, then communicating these two small blocks such operations be performed. Such repetition continues until all of the small size of the block are in communication \ (1 \) , easy to prove that the total number of such operations is minimal

Then come back and consider how to determine the legal point reduction, we can shrink the point of weakening conditions look into if \ ((u, v) \ ) does not make them on the same side of a communication block, note between \ ( S \) is not been reduced through the set of points, each taken \ (S \) in the start of the element \ (U \) , and all the \ (U \) point labeled with the adjacent edges, and then after sweep over \ (S \) , where all the points have not been taken out marked, if not marked and put it \ (U \) in the same block in and from a communication \ (S \) omitted in this it wants, so each point to be swept up \ (deg_i + 1 \) times, because I was chain analog \ (SET \) so the overall complexity is \ (O (n + m) \)

After completion of the final condensation point, calculate the number of edges per block Unicom and should have given number of sides is equal to the combined total number of edges can be determined whether a legitimate

//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=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 ans[N],tl[N],tr[N],stl[N],str[N],sz[N],tt,top,n,m;
int las[N],nxt[N],vis[N],bl[N],bg,tim;ll sum;
void solve(){
    sz[1]=0;fp(i,2,tim)sz[i]=sz[(i+1)>>1]+1;
    if(1ll*n*sz[tim]>1e6)return puts("-1"),void();
    printf("%d\n",sz[tim]);
    ++top,stl[top]=1,str[top]=tim;
    while(top<tim){
        fp(id,1,top){
            R int l=stl[id],r=str[id],mid=(l+r)>>1;
            fp(i,l,mid)ans[i]=0;
            fp(i,mid+1,r)ans[i]=1;
        }
        fp(i,1,n)putchar(ans[bl[i]]+'0');
        putchar('\n');
        fp(i,1,top)tl[i]=stl[i],tr[i]=str[i];tt=top;
        top=0;
        fp(id,1,tt){
            R int l=tl[id],r=tr[id],mid=(l+r)>>1;
            ++top,stl[top]=l,str[top]=mid;
            if(mid+1<=r)++top,stl[top]=mid+1,str[top]=r;
        }
    }
}
inline void del(R int x){
    las[nxt[x]]=las[x],nxt[las[x]]=nxt[x];
    if(x==bg)bg=nxt[x];
}
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),add(v,u);
    fp(i,1,n)las[i]=i-1,nxt[i]=i+1;
    las[1]=nxt[n]=0,bg=1;
    while(bg){
        R int sz=0;
        ++tim;
        go(bg)vis[v]=tim;
        for(R int u=bg;u;u=nxt[u])
            if(vis[u]!=tim)bl[u]=tim,++sz,del(u);
        sum+=1ll*sz*(sz-1)>>1;
    }
    if(sum+m!=1ll*n*(n-1)>>1)return puts("-1"),0;
    solve();
    return 0;
}

\ (Powder \)

First, we found that one thing

\[ \begin{aligned} &(a+b)^k=\sum_{i=0}^k{k\over i}a^ib^{k-i}\\ &{1\over k!}(a+b)^k=\sum_{i=0}^k{a^i\over i!}{b^{k-i}\over (k-i)!}\\ \end{aligned} \]

That is, if we already know the \ (a ^ i \) and \ (b ^ i \) , you can get direct convolution \ ((a + b) ^ i \)

Then we remember \ (f [i] [j ] \) said it was considering the first \ (i \) th items, spent a total of (j \) \ price, corresponding polynomial value of the contribution directly \ (NTT \) optimization on it

//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 P=998244353;
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=(1<<12)+5,M=105;
int fac[N],ifac[N],inv[15],r[15][N],rt[2][N],lim,d,len;
inline void swap(R int &x,R int &y){R int t=x;x=y,y=t;}
void init(int n=4096){
    fp(d,1,12){
        fp(i,1,(1<<d)-1)r[d][i]=(r[d][i>>1]>>1)|((i&1)<<(d-1));
        inv[d]=ksm(1<<d,P-2);
    }
    fac[0]=ifac[0]=1;fp(i,1,n)fac[i]=mul(fac[i-1],i);
    ifac[n]=ksm(fac[n],P-2);fd(i,n-1,1)ifac[i]=mul(ifac[i+1],i+1);
    for(R int t=(P-1)>>1,i=1,x,y;i<4096;i<<=1,t>>=1){
        x=ksm(3,t),y=ksm(332748118,t),rt[0][i]=rt[1][i]=1;
        fp(k,1,i-1){
            rt[1][i+k]=mul(rt[1][i+k-1],x),
            rt[0][i+k]=mul(rt[0][i+k-1],y);
        }
    }
}
void NTT(int *A,int ty){
    fp(i,0,lim-1)if(i<r[d][i])swap(A[i],A[r[d][i]]);
    int t;
    for(R int mid=1;mid<lim;mid<<=1)
        for(R int j=0;j<lim;j+=(mid<<1))
            fp(k,0,mid-1){
                A[j+k+mid]=dec(A[j+k],t=mul(A[j+k+mid],rt[ty][mid+k]));
                A[j+k]=add(A[j+k],t);
            }
    if(!ty)fp(i,0,lim-1)A[i]=mul(A[i],inv[d]);
}
void ADD(int *a,int *b,int *c){
    static int A[N],B[N];
    fp(i,0,len-1)A[i]=a[i],B[i]=b[i];
    fp(i,len,lim-1)A[i]=B[i]=0;
    NTT(A,1),NTT(B,1);
    fp(i,0,lim-1)A[i]=mul(A[i],B[i]);
    NTT(A,0);
    fp(i,0,len-1)upd(c[i],A[i]);
}
int a[M],c[M],g[M][N],f[2][M][N],vis[2][N],n,s,k,t,res;
int main(){
//  freopen("testdata.in","r",stdin);
    init();
    scanf("%d%d%d",&n,&s,&k);
    fp(i,1,n)scanf("%d%d",&c[i],&a[i]);
    lim=1;while(lim<=(k<<1))lim<<=1,++d;
    len=lim>>1;
    fp(i,1,n){
        R int x=1;
        fp(j,0,k)g[i][j]=mul(x,ifac[j]),x=mul(x,a[i]);
    }
    f[0][0][0]=1,vis[0][0]=1,t=0;
    fp(i,1,n){
        memset(f[t^1],0,sizeof(f[t^1]));
        memset(vis[t^1],0,sizeof(vis[t^1]));
        fp(j,0,s)if(vis[t][j]){
            vis[t^1][j]=1;
            fp(k,0,len-1)upd(f[t^1][j][k],f[t][j][k]);
            if(j+c[i]<=s){
                vis[t^1][j+c[i]]=1;
                ADD(f[t][j],g[i],f[t^1][j+c[i]]);
            }
        }
        t^=1;
    }
    fp(i,0,s)upd(res,f[t][i][k]);
    res=mul(res,fac[k]);
    printf("%d\n",res);
    return 0;
}

\(DODGERS\)

First, put everyone all over it \ (\ tim) a small point, and it is smaller than the maximum, and it is larger than the minimum are to find out, referred to as \ (ls_i \) and \ (rs_i \) , then it will a query \ (l, r \) contributes iff \ (l \ in [ls_i, i], r \ in [i, rs_i] \)

In this case the number of points is a two-dimensional problem, the President of trees on it, the complexity of the \ (O (n \ log n ) \)

Code in order to reduce the constant wrote himself \ (yy \) may persist Fenwick tree but it seems that complexity is \ (O (n \ log ^ 2n) \) is simply to run, but the Chairman of the tree ......

//minamoto
#include<bits/stdc++.h>
#define R register
#define pb emplace_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;
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';
}
typedef pair<int,int> pi;
const int N=1e6+5,M=3e7+5;
struct EG{int u,v;}E[N];
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;}
inline void swap(R int &x,R int &y){R int t=x;x=y,y=t;}
int c[M],id[N],dfn[N],ls[N],rs[N],st[N],vis[N],rd[N],top,tim,cnt;
vector<int>ID[N];vector<pi>sl[N];vector<int>::iterator it;
int n,m,q,T,lasans,s;
void clr(){
    fp(i,1,n+1){
        head[i]=dfn[i]=id[i]=0,
        ID[i].clear(),sl[i].clear();
//      vector<int>().swap(ID[i]),
//      vector<pi>().swap(sl[i]);
    }
    tot=cnt=tim=lasans=0;
}
void dfs(int u){dfn[u]=++tim;go(u)if(!dfn[v])dfs(v);}
int main(){
//  freopen("testdata.in","r",stdin);
    for(T=read();T;--T){
        n=read(),m=read(),q=read(),s=read();
        fp(i,1,m)E[i].u=read(),E[i].v=read();
        fd(i,m,1)add(E[i].u,E[i].v),add(E[i].v,E[i].u);
        fp(i,1,n)if(!dfn[i])dfs(i);
        fp(i,1,n)ls[i]=1,rs[i]=n;
        fp(u,1,n)go(u)if(dfn[v]<dfn[u])v<=u?cmax(ls[u],v+1):cmin(rs[u],v-1);
        fp(i,1,n){
            sl[i].pb(pi(ls[i],1)),sl[i].pb(pi(i+1,-1));
            sl[rs[i]+1].pb(ls[i],-1),sl[rs[i]+1].pb(i+1,1);
        }
        fp(i,1,n)ID[i].pb(0);
        fp(i,1,n){
            top=0;
            for(auto v:sl[i])for(R int x=v.fi;x<=n;x+=x&-x){
                if(!vis[x]){
                    st[++top]=x,vis[x]=1,c[++cnt]=c[id[x]],id[x]=cnt;
                    ID[x].pb(cnt);
                }
                c[id[x]]+=v.se;
            }
            fp(i,1,top)vis[st[i]]=0;
            rd[i]=cnt;
        }
        for(R int l,r;q;--q){
            l=read(),r=read(),l=(l+lasans*s-1)%n+1,r=(r+lasans*s-1)%n+1;
            if(l>r)swap(l,r);
            lasans=0;
            for(R int x=l;x;x-=x&-x){
                it=--lower_bound(ID[x].begin(),ID[x].end(),rd[r]+1);
                lasans+=c[*it];
            }
            print(lasans);
        }
        clr();
    }
    return Ot(),0;
}

Guess you like

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