noip33
T1
第一个猎人死的轮数等于在1号猎人之前死的猎人数+1,如果当前这个人没死,那么他死在一号猎人之前的概率为 \(\frac{w_{i}}{w_{1}+w_{i}}\),因为每死一个就会造成1的贡献,所以概率就是期望。最后答案记得+1。
Code
#include<cstdio>
#define MAX 100010
#define re register
#define int long long
namespace OMA
{
int n,w[MAX];
const int p = 998244353;
struct stream
{
template<typename type>inline stream &operator >>(type &s)
{
int w=1; s=0; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-')w=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ s=s*10+ch-'0'; ch=getchar(); }
return s*=w,*this;
}
}cin;
inline int quickpow(int a,int b)
{
int ans = 1;
while(b)
{
if(b&1)
{ ans = ans*a%p; }
a = a*a%p;
b >>= 1;
}
return ans;
}
int ans;
signed main()
{
cin >> n;
for(re int i=1; i<=n; i++)
{ cin >> w[i]; }
for(re int i=2; i<=n; i++)
{ (ans += w[i]*quickpow(w[1]+w[i],p-2)%p) %= p; }
printf("%lld\n",ans+1);
return 0;
}
}
signed main()
{ return OMA::main(); }
T2
再次是读题死亡,依旧是加粗了没看见。
注意符咒是对每个1进行操作,考试时看错题,样例还一下就过了QAQ。
正解:
线段树合并/启发式合并
首先,肯定是先把法术用了,再去用符咒,考虑用完法术后的序列。
设 \(l\) 为左边第一个1的位置,\(r\) 为右边第一个1的位置,\(xam\) 为中间最长的一段连续的0的长度,则答案为 \(\max(m-r+l-1,xam)\) 。 \(Push\;up\) 的时候维护一下就好。
那如何判断无解情况? 只需判断
注意一些坑点:比如一个城池可以掌握多种法术。
Code
#include<cstdio>
#define MAX 100010
#define re register
namespace OMA
{
int n,m,q;
int ans[MAX];
struct graph
{
int next;
int to;
}edge[MAX];
int cnt=1,head[MAX];
inline void add(int u,int v)
{ edge[++cnt] = (graph){head[u],v},head[u] = cnt; }
struct Segmnet_Tree
{
int tot;
struct TREE
{
int l,r;
int xam;
int size;
int ls,rs;
inline int len()
{ return m-r+l-1; }
}st[MAX<<5];
int root[MAX];
#define ls(p) st[p].ls
#define rs(p) st[p].rs
inline int max(int a,int b)
{ return a>b?a:b; }
inline void Push_up(int p)
{
st[p].size = st[ls(p)].size+st[rs(p)].size;
st[p].xam = max(st[ls(p)].xam,st[rs(p)].xam);
if(st[ls(p)].r&&st[rs(p)].l)
{ st[p].xam = max(st[p].xam,st[rs(p)].l-st[ls(p)].r-1); }
if(st[ls(p)].l)
{ st[p].l = st[ls(p)].l; }
else
{ st[p].l = st[rs(p)].l; }
if(st[rs(p)].r)
{ st[p].r = st[rs(p)].r; }
else
{ st[p].r = st[ls(p)].r; }
}
inline void insert(int &p,int l,int r,int x)
{
p = !p?++tot:p;
if(l==r)
{ st[p].size = 1,st[p].l = st[p].r = l; return ; }
int mid = (l+r)>>1;
if(x<=mid)
{ insert(ls(p),l,mid,x); }
else
{ insert(rs(p),mid+1,r,x); }
Push_up(p);
}
inline int merge(int p1,int p2,int l,int r)
{
if(!p1||!p2)
{ return p1|p2; }
if(l==r)
{ return p1; }
int mid = (l+r)>>1;
ls(p1) = merge(ls(p1),ls(p2),l,mid);
rs(p1) = merge(rs(p1),rs(p2),mid+1,r);
Push_up(p1);
return p1;
}
inline void dfs(int u)
{
for(re int i=head[u],v; i; i=edge[i].next)
{
v = edge[i].to; dfs(v);
root[u] = merge(root[u],root[v],1,m);
}
ans[u] = st[root[u]].size?max(st[root[u]].xam,st[root[u]].len()):-1;
}
}Tree;
struct stream
{
template<typename type>inline stream &operator >>(type &s)
{
int w=1; s=0; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-')w=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ s=s*10+ch-'0'; ch=getchar(); }
return s*=w,*this;
}
}cin;
signed main()
{
cin >> n >> m >> q;
for(re int i=1,u,v; i<=n-1; i++)
{ cin >> u >> v; add(u,v); }
for(re int i=1,u,p; i<=q; i++)
{ cin >> u >> p; Tree.insert(Tree.root[u],1,m,p); }
Tree.dfs(1);
for(re int i=1; i<=n; i++)
{ printf("%d\n",ans[i]); }
return 0;
}
}
signed main()
{ return OMA::main(); }
T3
完全图骗分 \(ans=(n-2)\times w\),20pts。
再加上一些乱搞,+10pts。
然而大帝 "乱搞" 有80pts orz。
正解:
神仙状压。
设 \(dp_{i,j}\) 表示当前所选集合为 \(i\) ,当前链的结尾为 \(j\),状态转移考虑两种情况:
在当前链的结尾新加入节点。
给当前链新增个集合/链上去。
预处理出每一种链边的总权值,某个链向另外一个链连边的权值。
或者说叫联通块?
关于状压枚举子集
设 \(S1\) 表示当前枚举的子集,\(S2\cup S1=S\),\(S\) 为全集。
for(re int s1=s; s1; s1=(s1-1)&s)
{ s2 = s^s1; }
Code
#include<cstdio>
#include<cstring>
#define re register
const int MAX = 1<<16;
namespace OMA
{
int n,m,top;
int dp[MAX][16],sum[MAX];
int dis1[16][16],dis2[MAX][16];
struct stream
{
template<typename type>inline stream &operator >>(type &s)
{
int w=1; s=0; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-')w=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ s=s*10+ch-'0'; ch=getchar(); }
return s*=w,*this;
}
}cin;
inline int max(int a,int b)
{ return a>b?a:b; }
signed main()
{
cin >> n >> m;
for(re int i=1,u,v,w; i<=m; i++)
{
cin >> u >> v >> w;
dis1[u][v] = w,dis1[v][u] = w;
}
top = (1<<n)-1;
for(re int i=1; i<=top; i++)
{
for(re int j=1; j<=n; j++)
{
for(re int k=j+1; k<=n; k++)
{
if(((i>>(j-1))&1) and ((i>>(k-1))&1))
{ sum[i] += dis1[j][k]; }
}
}
}
for(re int i=1; i<=top; i++)
{
for(re int j=1; j<=n; j++)
{
if((i>>(j-1))&1)
{
for(re int k=1; k<=n; k++)
{
if(not ((i>>(k-1))&1) and dis1[j][k])
{ dis2[i][k] += dis1[j][k]; }
}
}
}
}
memset(dp,128,sizeof(dp)); dp[1][1] = 0;
for(re int i=1; i<=top; i++)
{
for(re int j=1; j<=n; j++)
{
if(dp[i][j]<0)
{ continue ; }
for(re int k=1; k<=n; k++)
{
if((not (i>>(k-1))&1) and dis1[j][k])
{ dp[i|(1<<(k-1))][k] = max(dp[i|(1<<(k-1))][k],dp[i][j]+dis1[j][k]); }
}
int l = i^top;
for(re int k=l; k; k=(k-1)&l)
{ dp[i|k][j] = max(dp[i|k][j],dp[i][j]+sum[k]+dis2[k][j]); }
}
}
printf("%d\n",sum[top]-dp[top][n]);
return 0;
}
}
signed main()
{ return OMA::main(); }
noip33的更多相关文章
随机推荐
- buu signin
一.拖入ida,来静态分析F5大法好 要注意的点: 1._gmz_init_set_str() 这个函数,也是看师傅的wp,学到的,以后还是得多google, 本质上是这个函数: int mpz_in ...
- 20道Java实习生笔试面试选择题(内附答案解析)
1.以下对继承的描述错误的是(A) A.Java中的继承允许一个子类继承多个父类 B.父类更具有通用性,子类更具体 C.Java中的继承存在的传递性 D.当实例化子类时会递归调用父类中的构造方法 解 ...
- 洛谷P5463 小鱼比可爱(加强版) 题解
写博客不易,来玩会? 这道题我和dalao们的做法略有不同,我用的是归并排序做法qwq 归并排序求逆序对大家应该很清楚了,我这里就来讲讲如何用归并排序求出这道题的答案 让我们先观察一下规律 举个栗子, ...
- Codeforces Round#704 Div2 题解(A,B,C,D,E)
FST ROUND !!1 A Three swimmers: 直接整除一下向上取整就好了: #include <bits/stdc++.h> using namespace std; t ...
- Leetcode 春季打卡活动 第一题:225. 用队列实现栈
Leetcode 春季打卡活动 第一题:225. 用队列实现栈 Leetcode 春季打卡活动 第一题:225. 用队列实现栈 解题思路 这里用了非常简单的思路,就是在push函数上做点操作,让队头总 ...
- P3312 数表
P3312 数表 题意 求出 \[\sum_{i=1}^n\sum_{j=1}^m\sigma(\gcd(i,j))[\sigma(\gcd(i,j))\le a] \] 其中 \(\sigma\) ...
- dubbo(四)
前言 1.浅谈架构的发展 首先,要了解dubbo,就得了解,它是在什么背景下产生的?这就需要从架构的发展说起. 孟老师从事软件开发2008年份,那时候我上高一,那个时候,淘宝.京东都还没有火起来.那个 ...
- Rowid和Rownum
Rowid和Rownum对于数据库开发人员来说基本很少用到,因为在企业数据库开发中大多都是进行数据批处理,但是对于其他数据库人员来说还是会用到的. rowid和rownum都是虚列,但含义完全不同.r ...
- 如何让py生成pyd
pyd文件类似于C++中的dll,可以编译,但是看不到源代码. py转换成pyd参考链接:https://blog.csdn.net/weixin_44493841/article/details/1 ...
- Git,Linux,Ubuntu,Tmux的常用命令
常用的连接 Git命令 廖雪峰的Git教程 Git常用命令 ubuntu16.04之GitHub入门教程 Linux相关 tmux命令 Ubuntu常用命令速查手册 Linux 命令大全 其它工具 M ...