10.2 正睿國慶集訓測試1
目錄
2018.. Test - 總結
- A 陳太陽與取模
- B 陳太陽與路徑(樹形DP)
- C 陳太陽與開關
- 考試代碼
- B
- C
2018.. Test
時間:3.5h
期望得分:100+50+20
實際得分:40+45+20
比賽鏈接
總結
感覺自己是個zz
A 陳太陽與取模
題目鏈接
\[\begin{aligned}c\%x&\equiv (c\%A)\%x\\c\%x&\equiv (c-\lfloor\frac ca\rfloor*a)\%x\\c\%x&\equiv c\%x-\lfloor\frac ca\rfloor*a\%x\\(\lfloor\frac ca\rfloor*a)\%x&\equiv 0\end{aligned}\]
即\(x\)應是\(\lfloor\frac ca\rfloor*a\)的約數。
\(c\in[l,r]\),如果\(\frac la=\frac ra\)那麽\(x\)可以是\(\lfloor\frac ca\rfloor\times a\)的約數;
否則至少存在\(\lfloor\frac la\rfloor\times a\)和\((\lfloor\frac la\rfloor+1)\times a\),\(x\)只能是\(a\)的約數。
然後求約數個數就好了。。
// #include <cmath> #include <cstdio> #include <cctype> #include <algorithm> #define gc() getchar() typedef long long LL; inline LL read() { LL now=0;register char c=gc(); for(;!isdigit(c);c=gc()); for(;isdigit(c);now=now*10+c-'0',c=gc()); return now; } void Div(LL x) { LL ans=1; // for(int i=2,lim=sqrt(x); i<=lim; ++i) for(int i=2; 1ll*i*i<=x; ++i) if(!(x%i)) { int cnt=1; while(!(x%i)) x/=i, ++cnt; ans*=cnt; } if(x!=1) ans<<=1ll; printf("%lld\n",ans); } void Work() { LL L=read(),R=read(),A=read(); if(A>R) return (void)puts("-1"); L/A==R/A ? Div(L/A*A) : Div(A); } int main() { // freopen("ex_modulo3.in","r",stdin); for(int T=read(); T--; Work()); return 0; }
B 陳太陽與路徑(樹形DP)
題目鏈接
因為隨機樹的高度是有保證的,Prufer序列生成的隨機樹最大深度的期望為\(O(sqrt n)\),平均深度為\(O(\log n)\)。
所以我們可以用兩次復雜度為\(O(n*dep)\)的樹形DP求出每個點的答案。這樣空間復雜度也是\(O(n*dep)\)的。
DP數組的有用大小只與深度有關,可以用vector或者指針動態分配內存。另外以直徑的中點為根深度就可以/2。
這樣最終復雜度大概就是\(O(n\log n)\)。
另外可以用長鏈剖分做,對於每一條長鏈維護一個DP數組,第二遍DFS時只需要將非長鏈合並到長鏈上。
這樣任何樹都能做,復雜度\(O(n)\)。
——by dls
//
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 200000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=5e5+5;
int Enum,H[N],nxt[N<<1],to[N<<1],fa[N],pre[N],dis[N],dep[N];
int pool[30000000],*Now=pool,*F[N],*G[N];
LL ans[N];
char IN[MAXIN],*SS=IN,*TT=IN,OUT[6000000],*O=OUT;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
void print(LL x)
{
if(x>9) print(x/10);
*O++ = x%10+'0';
}
inline void AE(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
int BFS(int s)
{
static int q[N];
int h=0,t=1;
q[0]=s, dis[s]=pre[s]=0;
while(h<t)
{
int x=q[h++];
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=pre[x])
dis[v]=dis[x]+1, pre[v]=x, q[t++]=v;
}
return q[t];
}
void DFS0(int x)
{
int tmp=0;
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=fa[x])
fa[v]=x, DFS0(v), tmp=std::max(tmp,dep[v]+1);
dep[x]=tmp;
F[x]=Now, Now+=tmp+1, G[x]=Now, Now+=tmp+1;
}
void DFS1(int x)
{
int *f=F[x]; LL res=0;
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=fa[x])
{
DFS1(v); int *fv=F[v];
for(int j=0; j<=dep[v]; ++j)
res+=1ll*f[j]*fv[j], f[j]+=fv[j];
}
for(int i=dep[x]; i; --i) f[i]=f[i-1];
f[0]=1, ans[x]=res;
}
void DFS2(int x)
{
int *g=G[x],*gf=G[fa[x]],*f=F[x],*ff=F[fa[x]];
if(x!=1)
{
for(int i=1; i<=dep[x]; ++i)
{
g[i]=gf[i-1]+ff[i-1];
if(i>=2) g[i]-=f[i-2];
ans[x]+=1ll*g[i]*f[i];
}
}
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=fa[x]) DFS2(v);
}
int main()
{
// freopen("ex_diameter3.in","r",stdin);
// freopen("my.out","w",stdout);
int n=read();
for(int i=1; i<n; ++i) AE(read(),read());
int s=BFS(1), rt=BFS(s), d=dis[rt]>>1;
while(dis[rt]>d) rt=pre[rt];
DFS0(rt), DFS1(rt), DFS2(rt);
for(int i=1; i<n; ++i) print(ans[i]+1), *O++=' '; print(ans[n]+1);
fwrite(OUT,O-OUT,1,stdout);
return 0;
}
C 陳太陽與開關
題目鏈接
考試代碼
B
為什麽就是跑得比zzx慢。。(雖然一個分吧)
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 200000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=5e5+5;
int Enum,H[N],nxt[N<<1],to[N<<1],dgr[N],f[N],numx[N],num[N],Maxd;
LL ans[N];
char IN[MAXIN],*SS=IN,*TT=IN,OUT[6000000],*O=OUT;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
void print(LL x)
{
if(x>9) print(x/10);
*O++ = x%10+'0';
}
inline void AE(int u,int v)
{
++dgr[v], to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
++dgr[u], to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
void DFS0(int x,int fa)
{
int tmp=0;
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=fa)
DFS0(v,x), tmp=std::max(tmp,f[v]);
f[x]=tmp+1;
}
//void DFS1(int x,int fa)
//{
// if(dgr[x]==1) {fi[x]=0, se[x]=N; return;}
// int f=N,s=N;
// for(int i=H[x],v; i; i=nxt[i])
// if((v=to[i])!=fa)
// {
// DFS1(v,x);
// if(fi[v]<f) s=f, f=fi[v], pos[x]=v;
// else s=std::min(s,fi[v]);
// }
// ::f[x]=fi[x]=f+1, se[x]=s+1;
//}
//void DFS2(int x,int fa)
//{
// for(int i=H[x],v; i; i=nxt[i])
// if((v=to[i])!=fa)
// {
// if(pos[x]==v) f[v]=std::min(se[x]+1,f[v]);
// else f[v]=std::min(fi[x]+1,f[v]);
// DFS2(v,x);
// }
//}
void DFS3(int x,int fa,int d,int dep)
{
Maxd=std::max(Maxd,d);
++num[d], ++d;
if(!--dep) return;
for(int i=H[x]; i; i=nxt[i])
if(to[i]!=fa) DFS3(to[i],x,d,dep);
}
int main()
{
freopen("ex_diameter2.in","r",stdin);
freopen("my.out","w",stdout);
int n=read();
for(int i=1; i<n; ++i) AE(read(),read());
DFS0(1,1);
// DFS1(1,1), DFS2(1,1);
// for(int i=1; i<=n; ++i) printf("f[%d]=%d fi[%d]=%d se[%d]=%d\n",i,f[i],i,fi[i],i,se[i]);
for(int x=1; x<=n; ++x)
if(dgr[x]==1) ans[x]=1;
else
{
LL res=1; int tmp=f[x]-1; Maxd=1;
for(int i=H[x]; i; i=nxt[i])
{
DFS3(to[i],x,1,tmp);
for(int j=1; j<=Maxd&&num[j]; ++j)
res+=1ll*numx[j]*num[j], numx[j]+=num[j], num[j]=0;
}
for(int i=1; i<=tmp; ++i) numx[i]=0;
ans[x]=res;
}
for(int i=1; i<n; ++i) print(ans[i]), *O++=' '; print(ans[n]);
fwrite(OUT,O-OUT,1,stdout);
return 0;
}
C
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
#define mod 1000000007
typedef long long LL;
const int N=1e5+5;
int n,Enum,H[N],nxt[N<<1],to[N<<1];
bool mp[21][21],rev0[21],vis0[21];
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AE(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
int DFS0(int x)
{
int res=1; vis0[x]=1;
for(int i=1; i<=n; ++i)
if(!vis0[i] && (rev0[x]^rev0[i]^mp[x][i])) res+=DFS0(i);
return res;
}
bool Check()
{
memset(vis0,0,sizeof vis0);
return DFS0(1)==n;
}
void Subtask1()
{
memset(mp,0,sizeof mp);
for(int x=1; x<=n; ++x)
for(int i=H[x]; i; i=nxt[i]) mp[x][to[i]]=1;
int ans=1,all=(1<<n)-1;
for(int s=1; s<=all; ++s)
{
for(int i=0; i<n; ++i) if(s>>i&1) rev0[i+1]=1;
ans+=Check();
for(int i=0; i<n; ++i) if(s>>i&1) rev0[i+1]=0;
}
printf("%d\n",ans);
}
void Work()
{
Enum=0, memset(H,0,sizeof H);
n=read();
for(int i=1; i<n; ++i) AE(read(),read());
if(n<=20) {Subtask1(); return;}
}
int main()
{
// freopen("ex_trigger1.in","r",stdin);
// freopen(".out","w",stdout);
for(int T=read(); T--; Work());
return 0;
}
10.2 正睿國慶集訓測試1