2021.3.21 死に逝く君、WAに芽吹く憎悪
T3
题意:给定长度为n排列a,每次可以交换相邻2数,代价为1。可以随时停止操作,代价为\(\sum_{i=1}^n[a_i!=i]\)。求最小的代价,输出操作位置
我们不难证明,调整法有着极高的正确率,且期望操作次数极低
因为我们只有当每次交换会影响終态代价时才会换
而出现错误仅当最优策略为一次冒泡(或局部冒泡)时,所以当\(n\rightarrow \infty\)趋近为0
#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define read read1<ll>()
# define Type template<typename T>
Type T read1(){
T t=0;char k;bool vis=0;
do (k=getchar())=='-'&&(vis=1);while('0'>k||k>'9');
while('0'<=k&&k<='9')t=(t<<3)+(t<<1)+(k^'0'),k=getchar();
return vis?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
int s,a[200005],sta[200005];
int main(){//fre("pm");
s=read;
for(int i=1;i<=s;++i)
a[i]=read;int x=0;
while(1){
for(int i=1;i<s;++i)
if(a[i]==i+1||a[i+1]==i){
sta[++*sta]=i;
swap(a[i],a[i+1]);
}if(x==*sta)break;x=*sta;
for(int i=s;--i;)
if(a[i]==i+1||a[i+1]==i){
sta[++*sta]=i;
swap(a[i],a[i+1]);
}if(x==*sta)break;x=*sta;
}
printf("%d\n",*sta);
for(int i=1;i<=*sta;++i)printf("%d\n",sta[i]);
return 0;
}
T2
题意:\(\prod_{x_1,x_2...x_n\in [1,m]}lcm(x)^{\gcd(x)}\)
\(n\leq 10^8,m\leq 200000\)
\[\prod_{i=1}^m\prod_{a_i\leq m}lcm(a)^{gcd(a)[gcd(a)=i]}\\
=\prod_{i=1}^m\prod_{a_i\leq \frac{m}{i}}(i*lcm(a))^{i[gcd(a)=1]}\\
=\prod_{i=1}^m\prod_{a_i\leq \frac{m}{i}}(i*lcm(a))^{i\sum_{d|gcd(a)}\mu(d)}\\
=\prod_{i=1}^m\prod_{d=1}^{\frac{m}{i}}\prod_{a_i\leq \frac{m}{id}}(i*d*lcm(a))^{i\mu(d)}\\
=\prod_{T=1}^m\prod_{a_i\leq \frac{m}{T}}(T*lcm(a))^{\sum_{d|T}{T\over d}\mu(d)}
\\
\]
\[=\prod_{T=1}^m\prod_{a_i\leq \frac{m}{T}}(T*lcm(a))^{\varphi(T)}
\\
=\prod_{T=1}^m(T^{\lfloor\frac{m}{T}\rfloor^n}\prod_{a_i\leq \frac{m}{T}}lcm(a))^{\varphi(T)}
\\
\]
#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define read read1<ll>()
# define Type template<typename T>
Type T read1(){
T t=0;char k;bool vis=0;
do (k=getchar())=='-'&&(vis=1);while('0'>k||k>'9');
while('0'<=k&&k<='9')t=(t<<3)+(t<<1)+(k^'0'),k=getchar();
return vis?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
int s;
ll qkpow(ll n,int m,int mod){
ll t=1;
for(;m;m>>=1,n=n*n%mod)
(m&1)&&(t=t*n%mod);
return t;
}int pri[20005],phi[200005];
bool vis[200005];
void prep(const int N=200000){phi[1]=1;
for(int i=2;i<=N;++i){
if(!vis[i])pri[++pri[0]]=i,phi[i]=i-1;
for(int j=1;j<=pri[0]&&pri[j]*i<=N;vis[i*pri[j]]=1,++j)
if(!(i%pri[j]))phi[i*pri[j]]=phi[i]*pri[j];
else phi[i*pri[j]]=phi[i]*(pri[j]-1);
}
}int h[205],n;
# define mod 998244353
ll solve(int m){ll q=1;
for(int i=1;pri[i]<=m;++i){
int tot=0,v=1;
while(1ll*pri[i]*v<=m)
++tot,v*=pri[i];
int sum=h[tot]=m/v,t=0;
for(int j=tot;v/=pri[i],j--;sum+=h[j])
h[j]=m/v-sum;sum=qkpow(h[0],n,mod-1);
for(int j=1;j<=tot;++j){
h[j]+=h[j-1];
int tv=qkpow(h[j],n,mod-1)-sum+(mod-1);tv+1>=mod&&(tv-=mod-1);
t=(t+1ll*j*tv)%(mod-1);
sum=(sum+tv)%(mod-1);
}q=q*qkpow(pri[i],t,mod)%mod;
}
return q;
}
int main(){
fre("lg");
prep();
n=read;s=read;
ll ans=1;
for(int T=1;T<=s;++T){
ll t=qkpow(qkpow(T,qkpow(s/T,n,mod-1),mod)*solve(s/T)%mod,phi[T],mod);
ans=ans*t%mod;
}cout<<ans;
return 0;
}
T1
题意:给出序列n个数的值域区间,求此序列的期望逆序对数
题不是很难,考虑计算第\(j\)个数对第\(i\)个数产生的期望贡献
分类讨论
- \(l_i\leq l_j \leq r_i < r_j\)
\[(r_j-r_i)\rightarrow(r_j-l_j)\And(l_j-l_i)(r_j-l_j)\\
{{(2r_j-r_i-l_j)(r_i-l_j)\over 2}+l_j(r_j-l_j)-l_i(r_j-l_j)\over (r_i-l_i)(r_j-l_j)}\\
={{(2r_j-l_j)(r_i-l_j)-r_i(r_i-l_j)\over 2}+l_j(r_j-l_j)-l_i(r_j-l_j)\over (r_i-l_i)(r_j-l_j)}\\
={{2r_ir_j-(2r_j-l_j)l_j-r_i^2\over 2}+l_j(r_j-l_j)-l_i(r_j-l_j)\over (r_i-l_i)(r_j-l_j)}\\
\]
- \(l_j<l_i\leq r_j\leq r_i\)
\[0\rightarrow (r_j-l_i)\\
{(r_j-l_i)^2\over 2(r_j-l_j)(r_i-l_i)}\\
={r_j^2+l_i^2-2l_ir_j\over 2(r_j-l_j)(r_i-l_i)}\\
={r_j^2+(l_i^2-2l_ir_j)\over 2(r_j-l_j)(r_i-l_i)}
\]
- \(l_i\leq l_j<r_j\leq r_i\)
\[0\rightarrow (r_j-l_j)|(l_j-l_i)(r_j-l_j)\\
{{(r_j-l_j)^2\over 2}+l_j(r_j-l_j)-l_i(r_j-l_j)\over (r_j-l_j)(r_i-l_i)}
\]
- \(l_j<l_i<r_i<r_j\)
\[(r_j-r_i)\rightarrow (r_j-l_i)\\
{(2r_j-l_i-r_i)(r_i-l_i)\over 2(r_j-l_j)(r_i-l_i)}\\
={2r_j(r_i-l_i)-(l_i+r_i)(r_i-l_i)\over 2(r_j-l_j)(r_i-l_i)}
\]
-
\(r_i< l_j\)
直接查
下面这份代码因实现的问题可能会被卡时空,但是它是对的
#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define read read1<ll>()
# define Type template<typename T>
Type T read1(){
T t=0;char k;bool vis=0;
do (k=getchar())=='-'&&(vis=1);while('0'>k||k>'9');
while('0'<=k&&k<='9')t=(t<<3)+(t<<1)+(k^'0'),k=getchar();
return vis?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
# define mod 998244353ll
# define inv2 499122177ll
struct A{
int x,y;
A(int _x=0,int _y=0):x(_x),y(_y){}
A& operator +=(const A &b){return (x+=b.x)>=mod&&(x-=mod),(y+=b.y)>=mod&&(y-=mod),*this;}
A& operator -=(const A &b){return (x-=b.x)<0&&(x+=mod),(y-=b.y)<0&&(y+=mod),*this;}
A operator +(A b)const{return b+=*this;}
A operator -(A b)const{return A(x,y)-=b;}
};
struct B{
int x,y,z;
B(int _x=0,int _y=0,int _z=0):x(_x),y(_y),z(_z){}
B& operator +=(const B &b){return (x+=b.x)>=mod&&(x-=mod),(y+=b.y)>=mod&&(y-=mod),(z+=b.z)>=mod&&(z-=mod),*this;}
B& operator -=(const B &b){return (x-=b.x)<0&&(x+=mod),(y-=b.y)<0&&(y+=mod),(z-=b.z)<0&&(z+=mod),*this;}
B operator +(B b)const{return b+=*this;}
B operator -(B b)const{return B(x,y,z)-=b;}
};
Type struct node{
node *l,*r;
T v;
node():v(){l=r=NULL;}
};
node<B>*a[200005],*b[200005];
node<A>*d[200005],*c[200005],*g[200005];
int s;
Type void add(node<T>*& x,int w,T v,int l,int r){
if(!x)x=new node<T>;
x->v+=v;
if(l==r)return;
int mid=l+r>>1;
if(w<=mid)add(x->l,w,v,l,mid);
else add(x->r,w,v,mid+1,r);
}
Type T query(node<T>* x,int l,int r,int tl,int tr){
if(r<l)return T();
if(!x)return T();
if(l==tl&&r==tr)return x->v;
int mid=tl+tr>>1;
if(r<=mid)return query(x->l,l,r,tl,mid);
if(mid<l)return query(x->r,l,r,mid+1,tr);
return query(x->l,l,mid,tl,mid)+query(x->r,mid+1,r,mid+1,tr);
}
int fu[200005];
Type void add(node<T> **a,int x,int y,T t){while(x<=*fu)add(a[x],y,t,1,*fu),x+=x&-x;}
Type T query(node<T> **a,int x,int l,int r){
T t;
while(x)t+=query(a[x],l,r,1,*fu),x&=x-1;
return t;
}Type T query(node<T> **a,int xl,int xr,int l,int r){return query(a,xr,l,r)-query(a,xl-1,l,r);}
ll qkpow(ll n,ll m){
ll t=1;
for(;m;m>>=1){
if(m&1)t=t*n%mod;
n=n*n%mod;
}
return t;
}
pair<int,int>q[100005];
int main(){fre("rng");
s=read;ll t=0,ans=0;B k(0,0,0);A v(0,0);
for(int i=1;i<=s;++i)fu[++fu[0]]=read,fu[++fu[0]]=read,q[i]=make_pair(fu[fu[0]-1],fu[fu[0]]);
sort(fu+1,fu+*fu+1);
*fu=unique(fu+1,fu+*fu+1)-fu-1;
for(int i=1;i<=s;++i){
int l=q[i].first,r=q[i].second,xl=lower_bound(fu+1,fu+*fu+1,l)-fu,xr=lower_bound(fu+1,fu+*fu+1,r)-fu;
k=query(a,xl,xr,xr+1,*fu);
t=(t+k.x+1ll*r*k.y-1ll*l*k.z-inv2*r%mod*r%mod*query(d,xl,xr,xr+1,*fu).y)%mod;
k=query(b,xl,xr,1,xl-1);
t=(t+k.x+inv2*l%mod*l%mod*k.z-1ll*l*k.y)%mod;
v=query(c,xl,xr,xl,xr);
t=(t+v.x-1ll*l*v.y+mod)%mod;
v=query(d,1,xl-1,xr+1,*fu);
t=(t+1ll*(r-l)*v.x-inv2*(l+r)%mod*(r-l)%mod*v.y)%mod;
ll tv=qkpow(r-l,mod-2);
add(a,xl,xr,B((1ll*l*(r-l)+(mod-2*r+l)*l%mod*inv2)%mod*tv%mod,r*tv%mod,(r-l)*tv%mod));
add(b,xr,xl,B(1ll*r*r%mod*tv%mod*inv2%mod,r*tv%mod,tv));
add(c,xl,xr,A((inv2*(r-l)%mod*(r-l)+1ll*l*(r-l))%mod*tv%mod,(r-l)*tv%mod));
add(d,xl,xr,A(r*tv%mod,tv));
ans=(ans+t*tv)%mod;
v=query(g,xr+1,*fu,xr+1,*fu);
ans=(ans+v.x)%mod;
add(g,xl,xr,A(1));t=0;
}printf("%lld\n",(ans+mod)%mod);
return 0;
}
虽然可以用差分改成\(n\log_2n\),但我这份打的是\(n\log_2^2n\)的树套树 ☕
考场上头铁了,所以就盯着这道题打。debug不出来,想打下道题,但是一想到已经打出来了,就不由得不爽了起来,所以我就收获了0分的好成绩😄
因果乃旋转纺车,光彩之多面明镜
浮世苍茫,不过瞬逝幻梦
善恶爱诳,皆有定数
于命运之轮中
吞噬于黄泉之冥暗
呜呼,吾乃梦之戍人
幻恋之观者
唯于万华镜中,永世长存
浮世苍茫,不过瞬逝幻梦
善恶爱诳,皆有定数
于命运之轮中
吞噬于黄泉之冥暗
呜呼,吾乃梦之戍人
幻恋之观者
唯于万华镜中,永世长存

浙公网安备 33010602011771号