Loading

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);
}
posted @ 2021-10-27 21:41  AaMuXiiiiii  阅读(22)  评论(0编辑  收藏  举报