231011校内赛
T1 树上的数
题解
比上一次好一些的第一题
不过我还是没做出来
一眼树形
不过状态设计和转移不是很好列
容易想到对于子树枚举,记录
对于每一个节点的初始状态都是
为什么呢?
对于第二个状态很好理解,选一个只有一种情况
对于第一个则是因为会影响这个点做选择的只有从它到根节点这一段路径上的节点,自己想想就能明白
说完了初始状态说转移
对于子树的合并明显有
这个转移式的意思就是对于当前答案与子树答案相乘,因为是满足乘法原理
分别在当前统计过的位置选
统计完空位后别忘了用组合数统计当前节点需要选出来的位置的方案数
#include<bits/stdc++.h>
#define N 5010
#define mod 998244353
using namespace std;
int n,cnt,b[N],f[N][N],siz[N],tmp[N],fac[N],inv[N],dep[N];
vector<int>g[N];
int ksm(int x,int y){
int res = 1;
while(y){
if(y&1) res = 1ll*res*x%mod;
x = 1ll*x*x%mod;
y>>=1;
}
return res;
}
int C(int x,int y){
if(x<y) return 1;
return 1ll*fac[x]*inv[y]%mod*inv[x-y]%mod;
}
void dfs(int u){
siz[u] = f[u][1] = 1;
f[u][0] = n-dep[u];
for(int v : g[u]){
dfs(v);
for(int i = 0;i<=siz[u];i++)
for(int j = 0;j<=siz[v];j++)
tmp[i+j] = (tmp[i+j]+1ll*f[u][i]*f[v][j]%mod)%mod;
siz[u]+=siz[v];
for(int i = 0;i<=siz[u];i++){
f[u][i] = tmp[i];
tmp[i] = 0;
}
}
for(int i = b[u];i<=siz[u];i++)
tmp[i-b[u]] = 1ll*f[u][i]*C(i,b[u])%mod;
for(int i = 0;i<=siz[u];i++){
f[u][i] = tmp[i];
tmp[i] = 0;
}
}
int main(){
freopen("treei.in","r",stdin);
freopen("treei.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n;
fac[0] = 1;
for(int i = 1;i<=n;i++) fac[i] = 1ll*fac[i-1]*i%mod;
inv[n] = ksm(fac[n],mod-2);
for(int i = n-1;i>=0;i--) inv[i] = 1ll*inv[i+1]*(i+1)%mod;
dep[1] = 1;
for(int i = 2;i<=n;i++){
int x;cin>>x;
g[x].push_back(i);
dep[i] = dep[x]+1;
}
for(int i = 1;i<=n;i++)
cin>>b[i];
dfs(1);
cout<<f[1][0];
return 0;
}
T2 解方程
题解
一道说起来挺麻烦的数学题
当
此时,
而
令
假设已经知道
此时,上述式子中,
因此,只要知道模数为
故最终算法为不停递归,每次令
从这里也看出,不可能无解
计算
最终时间复杂度
由此也可以看出,对于测试点
前面只是讨论了测试点
当
只需要在解同余方程时强制要 求解
时间复杂度
#include<bits/stdc++.h>
#define int long long
using namespace std;
int cnt,pri[50];
void exgcd(int a,int b,int &x,int &y){
if(!b){
x = 1,y = 0;
return ;
}
exgcd(b,a%b,y,x);
y-=a/b*x;
}
int ksm(int x,int y,int p){
int res = 1;
while(y){
if(y&1) res = res*x%p;
x = x*x%p;
y>>=1;
}
return res;
}
int inv(int x,int p){
int a,b;
exgcd(x,p,a,b);
a = (a%p+p)%p;
return a;
}
int gcd(int a,int b){
return !b?a:gcd(b,a%b);
}
int solve(int a,int b,int k,int p){
if(p==1) return 1e9;
int phi = p;
for(int i = 1;i<=cnt;i++)
if(p%pri[i]==0) phi = phi/pri[i]*(pri[i]-1);
int g = gcd(p,phi),tmp = solve(a,b,k,g);
int v = (ksm(a,tmp,p)-b+p)%p*inv(k,p)%p,A,B;
exgcd(phi,p,A,B);
A = (A%p+p)%p;
A*=(v-tmp)/g;
A = (A%p+p)%p;
int x = phi*A+tmp;
int lcm = p/g*phi;
x = (x%lcm+lcm)%lcm;
if(x<1e9) x+=lcm;
return x;
}
signed main(){
freopen("equation.in","r",stdin);
freopen("equation.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int T;cin>>T;
while(T--){
int a,b,p,k;
cin>>a>>b>>p>>k;
cnt = 0;
int tmp = p;
for(int i = 2;i*i<=tmp;i++){
if(tmp%i==0){
while(tmp%i==0) tmp/=i;
pri[++cnt] = i;
}
}
if(tmp>1) pri[++cnt] = tmp;
cout<<solve(a,b,k,p)<<"\n";
}
return 0;
}
T3 网络
题解
我不会那就直接贴题解
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define yu (998244353)
inline void add(ll &x,ll y){x+=y;if(x>=yu)x-=yu;return;}
#define N 100010
ll n,m,k,x;
ll sum[N];
inline ll ksm(ll x,ll y=yu-2){
ll an=1;for(;y;y>>=1){
if(y&1)an=an*x%yu;
x=x*x%yu;
}return an;
}
inline ll gtd(){
/*ll an=0;for(int i=1;i<=min(k,x);i++){
add(an,min(k,x-i));
}*/if(x<=k+1){
return x*(x-1)/2%yu;
}return (k*(x-k-1)+(k+(x-k))*(2*k-x+1)/2)%yu;
}
inline ll gtf(ll x,ll y){x--;return (y*(2*y+1)%yu*(y+1)%yu*ksm(6)%yu-x*(2*x+1)%yu*(x+1)%yu*ksm(6)%yu+yu)%yu;}
inline ll gtl(ll x,ll y){x--;return ((y*(y+1)/2)%yu*(y*(y+1)/2%yu)%yu-(x*(x+1)/2)%yu*(x*(x+1)/2%yu)%yu+yu)%yu;}
inline ll gt(ll l,ll r){return (2*x*gtf(l,r)%yu-(2*gtl(l,r)+gtf(l,r))%yu+yu)%yu;}
inline ll gtb(){
// for(int i=1;i<=k;i++)sum[i]=2*i-1;for(int i=1;i<=k;i++)add(sum[i],sum[i-1]);
/*ll an=0;for(int i=1;i<=min(k,x);i++){
add(an,sum[min(k,x-i)]);
}*/if(x<=k+1){
return gtf(1,x-1);
}return (gtf(k,k)*(x-k-1)+gtf(x-k,k))%yu;
}
inline ll gth(){
/*for(int i=1;i<=k;i++)sum[i]=2*i-1;for(int i=1;i<=k;i++)add(sum[i],sum[i-1]);
ll an=0;for(ll i=1;i<=min(k,x);i++){
add(an,(2*i-1)*sum[min(k,x-i)]%yu);
}*/if(x<=k+1){
return gt(1,x-1);
}return (gtf(k,k)*(x-k-1)%yu*(x-k-1)%yu+gt(x-k,k))%yu;
}
int main(){
// freopen("test1.in","r",stdin);
freopen("grid.in","r",stdin);
freopen("grid.out","w",stdout);
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
ll ti;cin>>ti;while(ti--){
cin>>n>>m>>k>>x;x=min(x,2*k);ll tem=ksm(k),sum=ksm(k,n+m);
ll ans=yu-sum;
ll an=gtd();
add(ans,an*n%yu*m%yu*sum%yu*tem%yu*tem%yu);
an=gtb();
add(ans,yu-an*((n*(m-1)+(n-1)*m)%yu)%yu*sum%yu*tem%yu*tem%yu*tem%yu);
an=gth();
if(n>1&&m>1)add(ans,an*((n-1)*(m-1)%yu)%yu*sum%yu*tem%yu*tem%yu*tem%yu*tem%yu);
cout<<ans<<'\n';
}return 0;
}
个人认为比较简单的代码
下面是题解代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 998244353;
int Power(int x, int y) {
int ret = 1;
while (y) {
if (y & 1) ret = 1ll * ret * x % mod;
x = 1ll * x * x % mod, y >>= 1;
}
return ret;
}
int S1(int l, int r) { return 1ll * (l + r) * (r - l + 1) / 2 % mod; }
int S2r(int r) { return 1ll * r * (r + 1) % mod * (2 * r + 1) % mod * (mod + 1) / 6 % mod; }
int S2(int l, int r) { return (S2r(r) - S2r(l - 1) + mod) % mod; }
int S3r(int r) { return 1ll * S1(1, r) * S1(1, r) % mod; }
int S3(int l, int r) { return (S3r(r) - S3r(l - 1) + mod) % mod; }
int main() {
freopen("grid.in", "r", stdin);
freopen("grid.out", "w", stdout);
int t;
cin >> t;
while (t--) {
int n, m, K, x, ans = 0;
cin >> n >> m >> K >> x, x = min(x, K * 2);
if (x <= K + 1) {
ans = (ans + 1ll * x * (x - 1) / 2 % mod * Power(1ll * K * K % mod, mod - 2) % mod * n %
mod * m % mod) %
mod;
ans = (ans -
1ll * S2r(x - 1) * Power(1ll * K * K % mod * K % mod, mod - 2) % mod * n % mod *
(m - 1) % mod +
mod) %
mod;
ans = (ans -
1ll * S2r(x - 1) * Power(1ll * K * K % mod * K % mod, mod - 2) % mod * (n - 1) %
mod * m % mod +
mod) %
mod;
ans = (ans + 2ll * S3r(x - 1) * Power(1ll * K * K % mod * K % mod * K % mod, mod - 2) %
mod * (n - 1) % mod * (m - 1) % mod) %
mod;
ans = (ans + 2ll * x * x % mod * S1(1, x - 1) % mod *
Power(1ll * K * K % mod * K % mod * K % mod, mod - 2) % mod * (n - 1) %
mod * (m - 1) % mod) %
mod;
ans = (ans -
4ll * x % mod * S2(1, x - 1) % mod *
Power(1ll * K * K % mod * K % mod * K % mod, mod - 2) % mod * (n - 1) % mod *
(m - 1) % mod +
mod) %
mod;
ans = (ans -
1ll * S2r(x - 1) * Power(1ll * K * K % mod * K % mod * K % mod, mod - 2) % mod *
(n - 1) % mod * (m - 1) % mod +
mod) %
mod;
} else {
ans = (ans + 1ll * S1(x - K, K - 1) * Power(1ll * K * K % mod, mod - 2) % mod * n %
mod * m % mod) %
mod;
ans = (ans + 1ll * K * (x - K) % mod * Power(1ll * K * K % mod, mod - 2) % mod * n %
mod * m % mod) %
mod;
ans = (ans -
1ll * S2(x - K, K - 1) * Power(1ll * K * K % mod * K % mod, mod - 2) % mod * n %
mod * (m - 1) % mod +
mod) %
mod;
ans = (ans -
1ll * S2(x - K, K - 1) * Power(1ll * K * K % mod * K % mod, mod - 2) % mod *
(n - 1) % mod * m % mod +
mod) %
mod;
ans = (ans -
1ll * K * K % mod * (x - K) % mod * Power(1ll * K * K % mod * K % mod, mod - 2) %
mod * n % mod * (m - 1) % mod +
mod) %
mod;
ans = (ans -
1ll * K * K % mod * (x - K) % mod * Power(1ll * K * K % mod * K % mod, mod - 2) %
mod * (n - 1) % mod * m % mod +
mod) %
mod;
ans = (ans + 2ll * S3(x - K + 1, K) *
Power(1ll * K * K % mod * K % mod * K % mod, mod - 2) % mod * (n - 1) %
mod * (m - 1) % mod) %
mod;
ans = (ans + 2ll * x * x % mod * S1(x - K + 1, K) % mod *
Power(1ll * K * K % mod * K % mod * K % mod, mod - 2) % mod * (n - 1) %
mod * (m - 1) % mod) %
mod;
ans = (ans -
4ll * x % mod * S2(x - K + 1, K) % mod *
Power(1ll * K * K % mod * K % mod * K % mod, mod - 2) % mod * (n - 1) % mod *
(m - 1) % mod +
mod) %
mod;
ans = (ans + 2ll * K * K % mod * S1(1, x - K) % mod *
Power(1ll * K * K % mod * K % mod * K % mod, mod - 2) % mod * (n - 1) %
mod * (m - 1) % mod) %
mod;
ans = (ans -
1ll * S2(x - K, K - 1) * Power(1ll * K * K % mod * K % mod * K % mod, mod - 2) %
mod * (n - 1) % mod * (m - 1) % mod +
mod) %
mod;
ans = (ans -
1ll * K * K % mod * (x - K) % mod *
Power(1ll * K * K % mod * K % mod * K % mod, mod - 2) % mod * (n - 1) % mod *
(m - 1) % mod +
mod) %
mod;
}
ans = (ans - 1 + mod) % mod;
cout << 1ll * ans * Power(K, n + m) % mod << '\n';
}
}
T4
照样不会
梦与现实间挣扎着,所求为何
你可以借走我的文章,但你借不走我的智慧 虽然我是傻逼本文来自博客园,作者:cztq,转载请注明原文链接:https://www.cnblogs.com/cztq/p/17758134.html