蒟蒻做不来简单的csp模拟
T1 日期
Portkey
入门题看题解才做出来的qwq
#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
int i=0,f=1;char ch=0;
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') ch=getchar(),f=-1;
while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
return i*f;
}
int main(){
int a=in,b=in,cnt=0;
if(a==0||a>12) ++cnt;
if(b==0||b>31||(a==2&&b>28)) ++cnt;
cout<<cnt;
}
T2 和积和
Portkey
推柿子+疯狂前缀和
#include<bits/stdc++.h>
using namespace std;
#define in Read()
typedef long long ll;
ll in{
ll i=0,f=1;char ch=0;
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') ch=getchar(),f=-1;
while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
return i*f;
}
const int N=5e5+5;
const ll mod=1e9+7;
ll a[N],b[N],ab[N],A[N],B[N],AB[N];
// a,b: prefix of original a,b
// A,B: prefix of a,b
// ab: prefix of a*b
ll dec(ll a,ll b){return a<b?a-b+mod:a-b;}
int main(){
int n=in;
for(int i=1;i<=n;++i) a[i]=(a[i-1]+in)%mod,A[i]=(A[i-1]+a[i])%mod;
for(int i=1;i<=n;++i) b[i]=(b[i-1]+in)%mod,B[i]=(B[i-1]+b[i])%mod;
for(int i=1;i<=n;++i) ab[i]=a[i]*b[i]%mod,AB[i]=(AB[i-1]+ab[i])%mod;
ll res=0;
for(int i=1;i<=n;++i){
res=(res+(n-i+1)*ab[i-1]%mod)%mod;
res=(res+AB[n]-AB[i-1])%mod;
int tmpa=dec(A[n],A[i-1]),tmpb=dec(B[n],B[i-1]);
res=dec(res,a[i-1]*tmpb%mod);
res=dec(res,b[i-1]*tmpa%mod);
}
cout<<res;
return 0;
}
T3 网格图
Portkey
又是一道看题解才做出来的
我都想到排序了😢😢😢😢
排序以后考虑添加每一行/每一列,新加的行/列数量依次减少
#include<bits/stdc++.h>
using namespace std;
#define in Read()
#define int long long
int in{
int i=0,f=1;char ch=0;
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') ch=getchar(),f=-1;
while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
return i*f;
}
const int N=6e5+5;
int n,m,a[N],b[N];
signed main(){
n=in,m=in;
for(int i=1;i<=n;++i) a[i]=in;
for(int i=1;i<=m;++i) b[i]=in;
sort(a+1,a+n+1);
sort(b+1,b+m+1);
int i=2,j=2,r=1,c=1;
int res=a[1]*(m-1)+b[1]*(n-1);
while(i<=n&&j<=m){
if(a[i]<=b[j]){
res+=a[i]*(m-r);
++i,++c;
}else{
res+=b[j]*(n-c);
++j,++r;
}
}
cout<<res;
return 0;
}
T5 多叉堆
Portkey
并查集找爸爸,关键在于求子树合并
我傻不啦叽的一个劲想求完整结构的树的方案数qwq
实际上并查集的时候就两树合并了
合并:
c
n
t
u
′
=
c
n
t
u
×
c
n
t
v
×
(
s
i
z
u
′
−
1
s
i
z
v
)
cnt_{u'}=cnt_u\times cnt_v\times \binom{siz'_u-1}{siz_v}
cntu′=cntu×cntv×(sizvsizu′−1)
把谁是谁爸爸搞反了就很淦。。。
#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
int i=0,f=1;char ch=0;
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') ch=getchar(),f=-1;
while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
return i*f;
}
const int N=3e5+5,mod=1e9+7;
int n,q,fa[N],siz[N],cnt[N];
int fac[N],inv[N];
int mul(int a,int b){return 1ll*a*b%mod;}
int qpw(int a,int b){
int res=1;
while(b){
if(b&1) res=mul(res,a);
a=mul(a,a);
b>>=1;
}
return res;
}
int get(int x){return (x==fa[x])?x:fa[x]=get(fa[x]);}
void init(){
inv[0]=inv[1]=fac[0]=fac[1]=1;
for(int i=1;i<N;++i) fac[i]=mul(fac[i-1],i);
inv[N-1]=qpw(fac[N-1],mod-2);
for(int i=N-2;i>=1;--i) inv[i]=mul(inv[i+1],i+1);
return;
}
int C(int a,int b){return mul(fac[b],mul(inv[a],inv[b-a]));}
int main(){
init();
n=in,q=in;
for(int i=1;i<=n;++i) fa[i]=i,siz[i]=cnt[i]=1;
int las=0;
for(int i=1;i<=q;++i){
int opt=in;
if(opt==1){
int u=(in+las+1)%n,v=(in+las+1)%n;
swap(u,v);
if(!u) u=n;
if(!v) v=n;
u=get(u),v=get(v);
fa[v]=u;
siz[u]+=siz[v];
cnt[u]=mul(mul(cnt[u],cnt[v]),C(siz[v],siz[u]-1));
}else{
int x=(in+las+1)%n;
if(!x) x=n;
printf("%d\n",las=cnt[get(x)]);
}
}
return 0;
}
T4
最难的题,咕了
虽说是一道线段树qwq