CSP 后多校二
A.宝藏
签到题,随便写.
A_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS{
#define ll long long
#define lf double
#define ull unsigned ll
#define mp make_pair
#define lb lower_bound
#define ub upper_bound
#define lbt(x) ((x)&(-(x)))
#define Fill(x,y) memset(x,y,sizeof(x))
#define Copy(x,y) memcpy(x,y,sizeof(x))
#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
auto read=[]()->ll{
ll w=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) w=(w<<3)+(w<<1)+(ch^48),ch=getchar();
return cit?w:(-w);
};
} using namespace BSS;
const ll N=3e5+21;
ll m,n,ops,cnt;
ll lsh[N],pre[N];
struct I { ll w,t,id; } p[N];
struct II { ll x,id,res; } q[N];
struct Segment_Tree{
#define ls (x<<1)
#define rs (x<<1|1)
struct O { ll w,sum; } tr[N<<2];
void update(ll x,ll l,ll r,ll pos,ll sum){
if(l==r){
assert(l==pos),tr[x].sum+=sum,tr[x].w=tr[x].sum*lsh[l];
return ;
}
ll mid=(l+r)>>1;
pos<=mid ? update(ls,l,mid,pos,sum) : update(rs,mid+1,r,pos,sum);
tr[x].sum=tr[ls].sum+tr[rs].sum,tr[x].w=tr[ls].w+tr[rs].w;
}
ll query(ll x,ll l,ll r,ll pos){
if(l==r) return lsh[l]*pos;
ll mid=(l+r)>>1;
if(tr[ls].sum>pos) return query(ls,l,mid,pos);
else return tr[ls].w+query(rs,mid+1,r,pos-tr[ls].sum);
}
#undef ls
#undef rs
}A,B;
signed main(){
File(treasure);
n=read(),m=read(),ops=read(); ll x,y,z;
for(ll i=1;i<=n;i++){
p[i].id=i,p[i].w=read(),p[i].t=read();
lsh[i]=p[i].t;
}
sort(p+1,p+1+n,[](I i,I j)->bool{ return i.t<j.t; });
for(ll i=1;i<=n;i++) pre[i]=pre[i-1]+p[i].t;
sort(lsh+1,lsh+1+n),cnt=unique(lsh+1,lsh+1+n)-lsh-1;
for(ll i=1;i<=n;i++) p[i].t=lb(lsh+1,lsh+1+cnt,p[i].t)-lsh,A.update(1,1,n,p[i].t,1);
sort(p+1,p+1+n,[](I i,I j)->bool{ return i.w==j.w ? i.t>j.t : i.w>j.w; });
for(ll i=1;i<=ops;i++) q[i].x=read(),q[i].id=i;
sort(q+1,q+1+ops,[](II i,II j)->bool{ return i.x<j.x; });
A.update(1,1,n,p[1].t,-1);
for(ll i=1,j=1;i<=ops;i++){
x=q[i].x,y=(x-1)>>1;
if(pre[x]>m) { q[i].res=-1; continue; }
while(j<n and ( j<=y or lsh[p[j].t]+A.query(1,1,n,y)+B.query(1,1,n,y)>m )){
B.update(1,1,n,p[j].t,1),j++,A.update(1,1,n,p[j].t,-1);
}
q[i].res=p[j].w;
}
sort(q+1,q+1+ops,[](II i,II j)->bool{ return i.id<j.id; });
for(ll i=1;i<=ops;i++) printf("%lld\n",q[i].res);
exit(0);
}
B. 寻找道路
心态浮躁,想不出来,没有按照自己一般的做题方法进行.
事实上这样的题算是比较简单,每次贪心选就可以.
B_code
#include <bits/stdc++.h>
using namespace std;
namespace BSS {
#define ll long long
#define lf double
#define ull unsigned ll
#define pb push_back
#define mp make_pair
#define lb lower_bound
#define ub upper_bound
#define lbt(x) ((x) & (-(x)))
#define Fill(x, y) memset(x, y, sizeof(x))
#define Copy(x, y) memcpy(x, y, sizeof(x))
#define File(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout)
auto read = []() -> ll {
ll w = 0;
bool cit = 1;
char ch;
while (!isdigit(ch = getchar()))
if (ch == '-')
cit = 0;
while (isdigit(ch)) w = (w << 3) + (w << 1) + (ch ^ 48), ch = getchar();
return cit ? w : (-w);
};
} // namespace BSS
using namespace BSS;
const ll N = 6e6 + 21, mod = 1e9 + 7;
const ll inf = 0x3f3f3f3f3f3f3f3f;
ll m, n, ts;
ll dis[N], head[N], vis[N];
queue<ll> que;
vector<ll> vec;
struct I {
ll u, v, w, nxt;
} e[N << 1];
auto add = [](ll u, ll v, ll w) -> void {
e[++ts].u = u, e[ts].v = v, e[ts].w = w;
e[ts].nxt = head[u], head[u] = ts;
};
signed main() {
File(path);
n = read(), m = read();
ll u, v, w, ndis;
for (ll i = 1; i <= m; i++) {
u = read(), v = read(), w = read(), add(u, v, w);
}
Fill(dis, 0x3f), dis[1] = 0, que.push(1);
assert(dis[0] == inf);
while (que.size()) {
u = que.front(), que.pop();
for (ll i = head[u]; i; i = e[i].nxt) {
if ((!e[i].w) and dis[e[i].v]) {
dis[e[i].v] = 0, que.push(e[i].v);
}
}
}
for (ll i = 1; i <= n; i++)
if (!dis[i])
que.push(i);
while (que.size()) {
u = que.front(), que.pop(), vec.pb(u), ndis = dis[u];
while (que.size() and dis[u = que.front()] == ndis) que.pop(), vec.pb(u);
for (auto x : vec) {
vis[x] = 1;
for (ll i = head[x]; i; i = e[i].nxt) {
if ((dis[v = e[i].v] ^ inf) or e[i].w)
continue;
dis[v] = (ndis << 1ll) % mod, que.push(v);
}
}
for (auto x : vec) {
for (ll i = head[x]; i; i = e[i].nxt) {
if ((dis[v = e[i].v] ^ inf) or (!e[i].w))
continue;
dis[v] = ((ndis << 1ll) | 1ll) % mod, que.push(v);
}
}
vec.clear();
}
for (ll i = 2; i <= n; i++) printf("%lld ", (vis[i] ? dis[i] : -1ll));
puts(""), exit(0);
}
C. 猪国杀
神仙的 \(dp\),听到了一些沈队关于概率与期望 \(dp\) 的经验.
关于概率与期望的题目,一种可能性较高的思路就是期望线性性,甚至对于一些难以直接做的期望线性性可以构造出期望线性性,例如本题.
C_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS{
#define ll long long
#define lf double
#define ull unsigned ll
#define mp make_pair
#define lb lower_bound
#define ub upper_bound
#define lbt(x) ((x)&(-(x)))
#define Fill(x,y) memset(x,y,sizeof(x))
#define Copy(x,y) memcpy(x,y,sizeof(x))
#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
auto read=[]()->ll{
ll w=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) w=(w<<3)+(w<<1)+(ch^48),ch=getchar();
return cit?w:(-w);
};
} using namespace BSS;
const ll N=105,M=1005,mod=998244353;
ll m,n,s,ans;
ll C[M][M],po[M][M];
auto ksm=[](ll a,ll b,ll c,ll w=1)->ll{
for(a%=c;b;b>>=1,a=a*a%c) if(b&1) w=w*a%c;
return w%c;
};
auto g=[](ll i,ll j,ll k,ll w=0)->ll{
for(ll t=0;t<=i and m-k*j-t*(j-1)>=i;t++){
if(t&1) w=(w-C[i][t]*C[m-k*j-t*(j-1)][i]%mod+mod)%mod;
else w=(w+C[i][t]*C[m-k*j-t*(j-1)][i]%mod)%mod;
}
return w;
};
auto Sigma=[](ll i,ll j,ll k,ll w=0)->ll{
for(ll t=k;t<=n-i;t++)
w=(w+C[n-i][t]*po[s-j][n-i-t]%mod)%mod;
return w%mod;
};
signed main(){
File(legend);
n=read(),m=read(),s=read();
for(ll i=0;i<=1000;i++){
po[i][0]=1,C[i][0]=1;
for(ll j=1;j<=1000;j++) po[i][j]=po[i][j-1]*i%mod;
for(ll j=1;j<=i;j++) C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
}
for(ll i=0;i<=n;i++){
for(ll j=1;j<=s;j++)
for(ll k=1;k<=n-i;k++)
ans=(ans+g(i,j,k)*C[n][i]%mod*Sigma(i,j,k)%mod)%mod;
}
printf("%lld\n",ans*ksm(po[s][n],mod-2,mod)%mod),exit(0);
}
D. 数树
发现 \(m\) 很小,可能会考虑把 \(m\) 放在指数上.
于是在树上做一个 \(dp\) 就可以了,另外除以同构的方案数就好了.
D_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS{
#define ll long long
#define lf double
#define ull unsigned ll
#define pb push_back
#define mp make_pair
#define lb lower_bound
#define ub upper_bound
#define lbt(x) ((x)&(-(x)))
#define Fill(x,y) memset(x,y,sizeof(x))
#define Copy(x,y) memcpy(x,y,sizeof(x))
#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
auto read=[]()->ll{
ll w=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) w=(w<<3)+(w<<1)+(ch^48),ch=getchar();
return cit?w:(-w);
};
} using namespace BSS;
const ll N=3e3+21,M=12,mod=998244353;
ll m,n,U,ans;
ll per[M];
vector<ll> now[M];
auto ksm=[](ll a,ll b,ll c,ll w=1)->ll{
for(a%=c;b;b>>=1,a=a*a%c) if(b&1) w=w*a%c;
return w%c;
};
struct T2{
ll fa[M],son[M];
vector<ll> to[M];
inline void add(ll u,ll v){
to[u].pb(v),to[v].pb(u),son[u]|=(1<<v-1),son[v]|=(1<<u-1);
}
inline void getfa(ll u,ll dad){
fa[u]=dad;
for(auto v : to[u])
if(v!=dad) getfa(v,u);
}
}B;
struct T1{
ll g[1<<10];
ll f[N][M];
vector<ll> to[N];
inline void add(ll u,ll v){
to[u].pb(v),to[v].pb(u);
}
void dfs(ll u,ll dad){
for(auto v : to[u]) if(v!=dad) dfs(v,u);
fill(g,g+U+2,0),g[0]=1;
for(auto v : to[u]){
if(v==dad) continue;
for(ll i=U-1;i>=0;i--){
if(!g[i]) continue;
for(ll j=1;j<=m;j++){
if((i>>j-1)&1) continue;
(g[i|(1<<j-1)]+=g[i]*f[v][j]%mod)%mod;
}
}
}
for(ll i=1;i<=m;i++)
B.fa[i] ? f[u][i]=g[B.son[i]^(1<<B.fa[i]-1)] : f[u][i]=g[B.son[i]];
}
}A;
auto same=[](vector<ll> i,vector<ll> j)->bool{
if(i.size()!=j.size()) return 0;
for(ll k=0;k<(ll)i.size();k++) if(i[k]!=j[k]) return 0;
return 1;
};
signed main(){
File(count);
ll u,v,w,flag,cnt=0;
n=read(); for(ll i=2;i<=n;i++) A.add(read(),read());
m=read(); for(ll i=2;i<=m;i++) B.add(read(),read());
for(ll i=1;i<=m;i++) sort(B.to[i].begin(),B.to[i].end());
U=(1<<m)-1;
for(ll i=1;i<=m;i++){
B.getfa(i,0),A.dfs(1,0);
for(ll j=1;j<=n;j++) ans=(ans+A.f[j][i])%mod;
}
for(ll i=1;i<=m;i++) per[i]=i;
do{
flag=1;
for(ll i=1;i<=m;i++) now[per[i]]=B.to[i];
for(ll i=1;i<=m;i++){
for(auto &j : now[i]) j=per[j];
sort(now[i].begin(),now[i].end());
}
for(ll i=1;i<=m;i++){
if(same(B.to[i],now[i])) continue;
flag=0; break;
}
cnt+=flag;
}while(next_permutation(per+1,per+1+m));
printf("%lld\n",ans*ksm(cnt,mod-2,mod)%mod);
}