A salsman
题面:Luogu
题解:树形dp
考虑设\(dp[u]\)表示经过\(u\)及其子树的最大收益
停留次数就把子树的收益算一下排个序取前多少个就好了
第二问的话不是独自的有几种情况
- 这颗子树的选了的和没选的有收益相同的
- 有选了收益0的(也就是可选可不选)
- 子树里有不是独自的
分类讨论一下即可
D 子集选取
题面:Luogu
题解:
由手玩小样例可以得到\(ans=2^{nk}\)
显然对每个数可以分开计算
对于一个数,每一步都可以选或者不选,走k步,把选了的全部丢到最前面即可,方案数为\(2^k\)
因为每个数都可以选或者不选,所以总方案数\(2^{nk}\)
code
G 非诚勿扰
题面:Luogu
题解:树状数组,概率
s个候选人中选了第x个的概率为
\begin{aligned}
ans &=p* [(1-p)^{x-1}+(1-p)^{s+x-1}+...] \newline
&=p* (1-p)^{x-1}* \frac{1-0}{1-(1-p)^s}
\end{aligned}
可以发现我们要求的东西是一个类似逆序对的东西,上树状数组搞一下即可
code
H 套娃
题面:Luogu
题解:贪心
把out扔到multiset里面,每个in与能放的最大的out匹配
证明可以看\(\text{M}\)\(\color{red}{\text{_sea}}\)的博客
code
I 最小表示
题面:bzoj
题解:bitset 乱搞
考虑对于每条边\(u,v\)求出\(u\)能到的所有点和能到\(v\)的所有点,如果这两个有并集则这条边可以删掉
用拓扑排序求出能到某个点的所有点,再在反图上跑一遍即可
code
L 染色问题
题面:Luogu
题解:容斥
考虑\(i\)行\(j\)列不涂,\(k\)种颜色不用,随意涂
则此时答案为
\[{n\choose i}{m\choose j}{c\choose k}(c-k+1)^{(n-i)*(m-j)}\]
其中\(c-k+1\)是因为还可以不涂
于是容斥一下
\[ans=\sum_{i=0}^{n}{\sum_{j=0}^{m}{\sum_{k=0}^{c}{(-1)^{i+j+k}{n\choose i}{m\choose j}{c\choose k}(c-k+1)^{(n-i)*(m-j)}}}}\]
code
M 最大公约数
题面:Luogu
题解:
有一个结论:序列的gcd个数是\(O(\log)\)的
于是把r扫一遍,把所有gcd会改变的点扔到vector里面
不理解可以自己输出一下中间变量
code
A code
#include<bits/stdc++.h>
using namespace std;
inline void read(int& x)
{
x=0;char c=getchar();int f=1;
while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}
while(isdigit(c)) x=x*10+c-'0',c=getchar();
x*=f;
}
#define maxn 100005
int n,val[maxn],s[maxn],dp[maxn],f[maxn];
struct Edge
{
int fr,to;
}eg[maxn<<1];
int head[maxn],edgenum;
inline void add(int fr,int to)
{
eg[++edgenum]=(Edge){head[fr],to};
head[fr]=edgenum;
}
inline bool cmp(const int& x,const int& y)
{
return dp[x]>dp[y];
}
vector<int> ve;
void dfs(int rt,int fa)
{
dp[rt]=val[rt];
for(int i=head[rt];i;i=eg[i].fr)
if(eg[i].to!=fa) dfs(eg[i].to,rt);
ve.clear();
for(int i=head[rt];i;i=eg[i].fr)
if(eg[i].to!=fa&&dp[eg[i].to]>=0) ve.push_back(eg[i].to);
sort(ve.begin(),ve.end(),cmp);
int lim=min(s[rt]-1,(int)ve.size());
for(int i=0;i<lim;++i) dp[rt]+=dp[ve[i]],f[rt]|=f[ve[i]];
if(lim&&!dp[ve[lim-1]]) f[rt]=1;
if(lim<(int)ve.size()&&dp[ve[lim-1]]==dp[ve[lim]]) f[rt]=1;
}
int main()
{
read(n);s[1]=n;
for(int i=2;i<=n;++i) read(val[i]);
for(int i=2;i<=n;++i) read(s[i]);
int x,y;
for(int i=1;i<n;++i) read(x),read(y),add(x,y),add(y,x);
dfs(1,0);
printf("%d\n",dp[1]);
puts(f[1]?"solution is not unique":"solution is unique");
return 0;
}
D code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define p 1000000007
inline ll qpow(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y&1) ans=ans*x%p;
x=x*x%p;
y>>=1;
}
return ans;
}
int main()
{
ll n,k;
scanf("%lld%lld",&n,&k);
printf("%lld\n",qpow(2,n*k%(p-1)));
return 0;
}
G code
#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
template<typename T>
inline void read(T& x)
{
x=0;char c=getchar();int f=1;
while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}
while(isdigit(c)) x=x*10+c-'0',c=getchar();
x*=f;
}
#define lb long double
#define maxn 500005
lb c[maxn],p;
int n,m;
inline int lowbit(const int& x)
{
return x&(-x);
}
inline void update(const int& pos,const lb& val)
{
for(int i=pos;i<=n;i+=lowbit(i)) c[i]+=val;
}
inline lb query(const int& pos)
{
lb ans=0;
for(int i=pos;i;i-=lowbit(i)) ans+=c[i];
return ans;
}
vector<int> ve[maxn];
int main()
{
read(n),read(m);
scanf("%Lf",&p);
int x,y;
lb ans=0,tp;
register vector<int>::iterator it;
register int i;
for(i=1;i<=m;++i) read(x),read(y),ve[x].push_back(y);
for(i=1;i<=n;++i) sort(ve[i].begin(),ve[i].end());
for(i=1;i<=n;++i)
{
if(ve[i].empty()) continue;
tp=p/(1-pow(1-p,ve[i].size()));
for(it=ve[i].begin();it!=ve[i].end();++it,tp*=(1-p))
ans+=tp*(query(n)-query(*it)),update(*it,tp);
}
printf("%.2Lf\n",ans);
return 0;
}
H code
#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
template<typename T>
inline void read(T& x)
{
x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 200005
int n;
struct Item
{
int out,in,w;
inline friend bool operator < (Item a,Item b)
{
return a.w>b.w;
}
}it[maxn];
multiset<int> s;
multiset<int>::iterator tp;
int main()
{
read(n);
long long ans=0;
for(int i=1;i<=n;++i)
read(it[i].out),read(it[i].in),read(it[i].w),s.insert(it[i].out),ans+=1ll*it[i].w*it[i].in;
sort(it+1,it+n+1);
for(int i=1;i<=n;++i)
{
tp=s.lower_bound(it[i].in);
if(tp!=s.begin()) ans-=1ll*(*--tp)*it[i].w,s.erase(tp);
}
printf("%lld\n",ans);
return 0;
}
I code
#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
template<typename T>
inline void read(T& x)
{
x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 30005
int n,m,fr[maxn<<2],to[maxn<<2];
struct Graph
{
struct Edge
{
int fr,to;
}eg[maxn<<2];
int deg[maxn],head[maxn],edgenum;
bitset<maxn> bit[maxn];
inline void add(int fr,int to)
{
eg[++edgenum]=(Edge){head[fr],to};
head[fr]=edgenum;++deg[to];
}
void toposort()
{
queue<int> q;
while(!q.empty()) q.pop();
for(int i=1;i<=n;++i) if(!deg[i]) q.push(i);
while(!q.empty())
{
int tp=q.front();q.pop();
for(int i=head[tp];i;i=eg[i].fr)
{
bit[eg[i].to]|=bit[tp],bit[eg[i].to][tp]=1;
if(!--deg[eg[i].to]) q.push(eg[i].to);
}
}
}
}G,G_rev;
int main()
{
read(n),read(m);
int ans=0;
for(int i=1;i<=m;++i)
{
read(fr[i]),read(to[i]);
G.add(fr[i],to[i]),G_rev.add(to[i],fr[i]);
}
G.toposort();G_rev.toposort();
for(int i=1;i<=m;++i)
if((G.bit[to[i]]&G_rev.bit[fr[i]]).any()) ++ans;
printf("%d\n",ans);
return 0;
}
L code
#include<bits/stdc++.h>
using namespace std;
inline void read(int& x)
{
x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 405
#define p 1000000007
#define ll long long
int n,m,c,fac[maxn],inv[maxn],Pow[maxn*maxn];
inline int qpow(int x,int y)
{
int ans=1;
while(y)
{
if(y&1) ans=1ll*ans*x%p;
x=1ll*x*x%p;
y>>=1;
}
return ans;
}
inline int C(int n,int m)
{
return 1ll*fac[n]*inv[m]%p*inv[n-m]%p;
}
int main()
{
read(n),read(m),read(c);
fac[0]=inv[0]=1;
for(int i=1;i<=400;++i) fac[i]=1ll*fac[i-1]*i%p;
inv[400]=qpow(fac[400],p-2);
for(int i=399;i;--i) inv[i]=1ll*inv[i+1]*(i+1)%p;
ll ans=0,tp;
for(int k=0;k<=c;++k)
{
Pow[0]=1;
for(int i=1;i<=n*m;++i) Pow[i]=1ll*Pow[i-1]*(c-k+1)%p;
for(int i=0;i<=n;++i)
for(int j=0;j<=m;++j)
{
tp=1ll*C(n,i)*C(m,j)%p*C(c,k)%p*Pow[(n-i)*(m-j)]%p;
if((i+j+k)&1) ans-=tp;
else ans+=tp;
}
}
ans=(ans%p+p)%p;
printf("%lld\n",ans);
return 0;
}
M code
#include<bits/stdc++.h>
using namespace std;
template<typename T>
inline void read(T& x)
{
x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 100005
int n;
long long ans,a[maxn];
vector<int> ve,tp;
template<typename T>
T gcd(T a,T b)
{
if(!b) return a;
return gcd(b,a%b);
}
int main()
{
read(n);
for(int i=1;i<=n;++i) read(a[i]),ans=max(ans,a[i]);
ve.push_back(1);
for(int i=2;i<=n;++i)
{
tp.clear();tp.push_back(1);
for(unsigned j=0;j<ve.size();++j)
{
#define tmp ve[j]
a[tmp]=gcd(a[tmp],a[i]);
ans=max(ans,(i-tmp+1)*a[tmp]);
if(!j||a[tmp]!=a[ve[j-1]]) tp.push_back(tmp);
}
ve=tp;
if(a[ve.back()]!=a[i]) ve.push_back(i);
}
printf("%lld\n",ans);
return 0;
}