CSP-S模拟30
CSP-S模拟30
垃圾场
A. 灯若辰星 (light)
打表题。
题意就是求第一类、第二类斯特林数 \(\mod 2\) 意义下的值。
Code:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int Size=(1<<20)+1;
char buf[Size],*p1=buf,*p2=buf;
char buffer[Size];
int op1=-1;
const int op2=Size-1;
#define getchar() \
(tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt) \
? EOF \
: *ss++)
char In[1<<20],*ss=In,*tt=In;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
int q;
int op,n,m;
inline int f(int n,int m)
{
int a=n/2,b=m-(n+1)/2;
if((!n*m)||m>n) return 0;
if(b<0||b>a) return 0;
return ((a&b)==b);
}
inline int g(int n,int m)
{
int a=n-1-m/2,b=n-m;
if((!n*m)||m>n) return 0;
if(b<0||b>a) return 0;
return ((a&b)==b);
}
inline void solve()
{
op=read();
n=read();
m=read();
if(n==0&&m==0) cout<<"1";
else if(op==1) cout<<f(n,m);
else cout<<g(n,m);
}
signed main()
{
freopen("light.in","r",stdin);
freopen("light.out","w",stdout);
q=read();
while(q--) solve();
}
B. 彻天之火 (fire)
异或哈希。
答案 \(= n − 1−\) 交集的最大值。
对于每条边 \(i\),假设覆盖它的路径集合是 \(S_i\),那么出现次数最多的 \(S_i\) 的出现次数就是交集的最大值。
给每条路径随机一个 \([0, 2^{63})\) 内的权值,每条边的权值取成覆盖它的路径权值的异或和,就可以大概率表示出不同的覆盖集合。
异或差分甚至不需要求出 lca,复杂度 \(O(n + m)\)。
证明是对的很难。但手模发现这样做可以覆盖所有情况。
Code:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int Size=(1<<20)+1;
char buf[Size],*p1=buf,*p2=buf;
char buffer[Size];
int op1=-1;
const int op2=Size-1;
#define getchar() \
(tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt) \
? EOF \
: *ss++)
char In[1<<20],*ss=In,*tt=In;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
int n,m;
const int N=1<<20;
vector<int> E[1<<20];
int u[N],v[N];
// int bcj[1<<20];
// int f[1<<20];
// int dep[1<<20];
// int find(int x)
// {
// if(x==bcj[x]) return x;
// return bcj[x]=find(bcj[x]);
// }
int cntt;
mt19937_64 rnd(time(0));
// int val[N];
int pval[N];
unordered_map<int,int> mp;
void dfs(int p,int fa)
{
// int nw=0;
for(int to:E[p])
{
if(to==fa) continue;
dfs(to,p);
pval[p]^=pval[to];
}
if(p==1) return;
// cout<<p<<" "<<pval[p]<<"\n";
// mp[pval[p]]++;
// cntt=max(cntt,mp[pval[p]]);
// nw^=pval[p];
mp[pval[p]]++;
cntt=max(cntt,mp[pval[p]]);
// pval[p]=nw;
// f[p]=fa;
// dep[p]=dep[fa]+1;
// for(int to:E[p])
// {
// if(to==fa) continue;
// dfs(to,p);
// }
}
// void init()
// {
// for(int i=1;i<=n;i++) bcj[i]=i;
// dfs(1,0);
// }
// int Lca(int u,int v)
// {
// int cnt=0;
// while(bcj[u]!=bcj[v])
// {
// if(dep[u]<dep[v]) swap(u,v);
// cnt++;
// int top=find(u);
// bcj[top]=find(f[top]);
// u=bcj[top];
// }
// return cnt;
// }
int solve1()
{
return 0;
// init();
// int cnt=0;
// for(int i=1;i<=m;i++)
// {
// cnt+=Lca(u[i],v[i]);
// }
// return cnt;
}
int solve2()
{
for(int i=1;i<=m;i++)
{
int nw=(rnd()>>1);
// cout<<nw<<"\n";
pval[u[i]]^=nw;
pval[v[i]]^=nw;
}
dfs(1,0);
// cout<<cntt<<"\n";
return cntt;
}
signed main()
{
// #ifndef ONLINE_JUDGE
freopen("fire.in","r",stdin);
freopen("fire.out","w",stdout);
n=read();
m=read();
for(int i=1;i<n;i++)
{
int u=read(),v=read();
E[u].push_back(v);
E[v].push_back(u);
}
for(int i=1;i<=m;i++)
{
u[i]=read();
v[i]=read();
// if(u[i]==v[i]) { i--,m--; }
}
int ans=max(solve1(),solve2());
cout<<max(0ll,n-1-ans)<<"\n";
// #endif
//mt19937_64 myrand(time(0));
return 0;
}
C. 完美记忆 (perfect)
Code:
D. 未来程序 (program)
Code:
以下是博客签名,正文无关
本文来自博客园,作者:Wy_x,转载请在文首注明原文链接:https://www.cnblogs.com/Wy-x/p/19144292
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC-BY-NC-SA 4.0 协议)进行许可。

浙公网安备 33010602011771号