来了一场既没有$c++11$也没有$O2$的考试。
然后喜闻乐见的出现了一些$CE$,以及被卡常的。
然而与我没有关系,$T1$想到了最高的一档暴力(正解被卡常除外)
然而里面用到了$map$,没$O2$跑的是真的慢,最后拿了个不高不低的$50pts$
然后$T2$是神仙题,$O(n^3)$的$dp$我是天生恐惧。就算改题也是尝试理解了好久。
然后牛一直说它简单,然而给我讲并没有听明白。
哭了,太菜了听啥都像嘲讽。他们不懂底层人民的生活。
虽说我到现在都不明白暴力为什么会挂。
$T3$的最高分$20$居然死信仰的$puts("0")$。数据真神奇,然后还有的人$5pts$思路挺神仙的。。
正解更神仙,完全想不到。
考后改题时间都砸$T2$上了,到处问问了两个半小时只有一个人给我讲,还没讲明白(不敢继续问了23333
后来发现$T1$比较简单就把$T1$弄了下来,然后继续到处问$T2$。很晚很晚才问明白然后$AC$
然后就没时间搞$T3$了。大概思想明白。可以看看$AK$神们的博客。
状态还是很差。快点调整回来啊!!!
T1:space
大意:四维空间,有四个排列$A,B,C,D$。$(i,j,k,l) \rightarrow (A_i,B_j,C_k,D_l)$的代价为$1$。其余代价为$2$。求最小代价的经过所有点的回路。$n \le 10^5$
排列交换当成建图貌似渐渐成为了套路。?
如果我们对四个维度所有点一起连边,那么最后的代价就是$n^4+$环的个数。
每个四维环都是由四个一维环拼接出来的。改变定义设$A_i$表示大小为$i$的环有多少个。
$ans=n^4+A_iB_jC_kD_l\frac{i,j,k,l}{lcm(i,j,k,l)}$
$A$的数量级别是$O(\sqrt{n})$的。所以总复杂度是$O(n^2logn)$的。
然后对前后两个一组分组,$meet \ in \ middle$。
大概是个莫反。对于每种质因子考虑可以得到$\frac{abcd}{lcm(a,b,c,d)} = gcd(a,b)gcd(c,d)gcd(lcm(a,b),lcm(c,d))$
这样就可以把前后两部分分开。$(A_i,i,B_j,j) \rightarrow (A_iB_jgcd(i,j),lcm(i,j))$。得到新的二元组。
然后问题就在于二元组合并。懒得写公式了:
最后面的只与$Q$有关。可以预处理。我们对于每个$pair$把$second$分解质因数这样就能在合法的复杂度内求出$\varphi$和枚举约数。
然后就没了。但是因为没开$O2$所以$STL::map$超慢。手写哈希表是必要的(存$F$用)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define S 211111 4 #define mod 998244353 5 int w[S],al[S],n,ans,A[S],B[S],C[S],D[S],a[S],b[S],c[S],d[S],X,Y,T[S]; 6 vector<int>_dv[S],_t[S]; 7 struct hashmap{ 8 #define $ 10000007 9 int fir[$],l[$],to[$],v[$],ec; 10 int&operator[](int x){int r=x%$; 11 for(int i=fir[r];i;i=l[i])if(to[i]==x)return v[i]; 12 l[++ec]=fir[r];fir[r]=ec;to[ec]=x;return v[ec]; 13 } 14 }F; 15 int mo(int x){return x>=mod?x-mod:x;} 16 int gcd(int a,int b){return b?gcd(b,a%b):a;} 17 struct s{ 18 int a; vector<int>b,t; 19 void init(int x,int y,int z,int w){ 20 a=1ll*x*y*gcd(z,w)%mod; 21 for(int i=0;i<_dv[z].size();++i)T[_dv[z][i]]=max(T[_dv[z][i]],_t[z][i]); 22 for(int i=0;i<_dv[w].size();++i)T[_dv[w][i]]=max(T[_dv[w][i]],_t[w][i]); 23 for(int i=0;i<_dv[z].size();++i)b.push_back(_dv[z][i]), t.push_back(T[_dv[z][i]]),T[_dv[z][i]]=0; 24 for(int i=0;i<_dv[w].size();++i)if(T[_dv[w][i]])b.push_back(_dv[w][i]), t.push_back(T[_dv[w][i]]),T[_dv[w][i]]=0; 25 } 26 }x[S],y[S]; 27 int read(){ 28 register int p=0;register char ch=getchar(); 29 while(!isdigit(ch))ch=getchar(); 30 while(isdigit(ch))p=(p<<3)+(p<<1)+ch-48,ch=getchar(); 31 return p; 32 } 33 void init(int*M,int*m){ 34 for(int i=1;i<=n;++i)w[i]=read(),al[i]=0; 35 for(int i=1;i<=n;++i)if(!al[i]){ 36 int p=i,c=1;al[p]=1; 37 while(!al[w[p]])p=w[p],al[p]=1,c++; 38 M[c]++; 39 }for(int i=1;i<=n;++i)if(M[i])m[++m[0]]=i; 40 } 41 void ctb(int o,int n,int w){ 42 if(n==y[o].t.size()){F[w]=mo(F[w]+y[o].a);return;} 43 for(int j=0;j<=y[o].t[n];++j)ctb(o,n+1,w),w*=y[o].b[n]; 44 } 45 int ask(int o,int n,int w,int phi,int ans=0){ 46 if(n==x[o].t.size())return 1ll*F[w]*phi%mod; 47 for(int j=0;j<=x[o].t[n];++j)ans=mo(ans+ask(o,n+1,w,phi)),w*=x[o].b[n],phi=1ll*phi*(x[o].b[n]-(j?0:1)); 48 return ans; 49 } 50 int main(){//freopen("space20.in","r",stdin); 51 cin>>n;init(A,a);init(B,b);init(C,c);init(D,d); 52 for(int i=2;i<=n;++i)if(_dv[i].empty())for(int j=i;j<=n;j+=i){ 53 int x=j,c=0;_dv[j].push_back(i); 54 while(x%i==0)c++,x/=i; _t[j].push_back(c); 55 } 56 for(int i=1;i<=a[0];++i)for(int j=1;j<=b[0];++j)x[++X].init(A[a[i]],B[b[j]],a[i],b[j]); 57 for(int i=1;i<=c[0];++i)for(int j=1;j<=d[0];++j)y[++Y].init(C[c[i]],D[d[j]],c[i],d[j]); 58 for(int i=1;i<=Y;++i)ctb(i,0,1); 59 for(int i=1;i<=X;++i)ans=(ans+1ll*x[i].a*ask(i,0,1,1))%mod; 60 cout<<(ans+1ll*n*n%mod*n%mod*n)%mod<<endl; 61 }
T2:party
大意:树上有些点上有人,要求移动后形成一个联通块。(每点最多一个人)最小化总移动距离。$n \le 200$
神仙神仙神仙题。
设$dp[i][j]$表示,以$i$为根的子树中,不考虑$i$节点上的人,剩下在子树内形成了一个大小为$j$的联通块的最小代价。
默认剩下的$cnt-j$个人都围在$i$点上,且不考虑从$i$子树外到达$i$所用的步数。
那么在我们枚举一个根节点之后进行$dp$。考虑加入一个子树时会发生什么:
1)最后这个子树里一个人也没有。$dp[i][j]+=dp[son][0]+cnt[son]$。就是所有堆在$son$的人都上涌到$i$。因为不考虑从上面来的代价,所以只有$cnt[son]$有代价。
2)枚举这个子树里最后有多少人。$dp[i][j]=\min\limits_{k=1}^{j} (dp[i][j],dp[i][j-k]+dp[son][k]+ | k-sz[son] | )$
这里的绝对值非常妙。因为让外部走入和从内部走出的代价都是这个差值。
具体实现类似于一个背包。为了本层只更新本层,所以要倒着枚举$j$。
总的时间复杂度是$O(n^3)$的。
T3:wang
大意:要求设计值域定义域均为$Z$的函数$F$满足$F(2F(x)-x+1)=F(x)+C$。($C$为给定常数)。给定$n$对$(X,Y)$要求最小化$\sum\limits_{i=1}^{n} | F(X_i) - Y_i |$
时间不够。先鸽了。