2021.8.8考试总结[NOIP模拟33]
T1 Hunter
考场上一看期望直接状压拿了$45pts$跑了。结果正解只用$4$行?
把问题转化为一号猎人之前死的猎人数的期望加一。
期望的线性性。
对每个猎人$i$,$w_i+w_1$种情况中有$w_i$种死于一号猎人之前,故期望为$\frac{w_i}{w_i+w_1}$。
枚举累加即可。
$code:$


1 #include<bits/stdc++.h>
2 #define rin register signed
3 #define int long long
4 using namespace std;
5 const int NN=1e5+5,p=998244353;
6 int n,w[NN],f[1<<20],inv[1<<20],iv[NN],ans;
7 inline int read(){
8 int x=0,f=1; char ch=getchar();
9 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
10 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
11 return x*f;
12 }
13 inline void write(int x){
14 char ch[20]; int len=0;
15 if(x<0) putchar('-'), x=~x+1;
16 do{
17 ch[len++]=x%10+(1<<5)+(1<<4);
18 x/=10;
19 }while(x);
20 for(rin i=len-1;i>=0;--i) putchar(ch[i]);
21 return;
22 }
23 inline int qpow(int a,int b){
24 int res=1;
25 while(b){
26 if(b&1) res=res*a%p;
27 a=a*a%p;
28 b>>=1;
29 }
30 return res;
31 }
32 signed main(){
33 n=read(); f[0]=1;
34 for(int i=1;i<=n;i++) w[i]=read(), iv[i]=qpow(w[i],p-2);
35 for(int i=2;i<=n;i++)
36 (ans+=w[i]*qpow(w[1]+w[i],p-2)%p)%=p;
37 write(ans+1); putchar('\n');
38 return 0;
39 }
T1
T2 Defence
不难想到最优策略是先用法术再用符咒,而最后答案是前缀零,后缀零的和与区间中最长零串取$min$。动态开点线段树向上合并即可。
以上思路是考场看题$10min$后出的。然后线段树假上加假,$WA+MLE$掉成样例分。。
线段树合并太长时间不打了,细节不清,答案在最后统一记导致合并时只能新开节点。
玫瑰花精的印象不深,原来打过一样的$pushup$,要特判儿子是否为空,但这次又忘了。这算挂$91pts$吗?
$code:$


1 #include<bits/stdc++.h>
2 using namespace std;
3 const int NN=1e5+5;
4 int n,m,q,to[NN<<1],nex[NN<<1],head[NN<<1],num,ans[NN];
5 inline int read(){
6 int x=0,f=1; char ch=getchar();
7 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
8 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
9 return x*f;
10 }
11 inline void write(int x){
12 char ch[20]; int len=0;
13 if(x<0) putchar('-'), x=~x+1;
14 do{
15 ch[len++]=x%10+(1<<5)+(1<<4);
16 x/=10;
17 }while(x);
18 for(int i=len-1;i>=0;--i) putchar(ch[i]);
19 return;
20 }
21 inline void add(int a,int b){
22 to[++num]=b; nex[num]=head[a]; head[a]=num;
23 to[++num]=a; nex[num]=head[b]; head[b]=num;
24 }
25 struct segment_tree{
26 int tot,root[NN],mx[NN*40],lc[NN*40],rc[NN*40],lz[NN*40],rz[NN*40];
27 void pushup(int rt){
28 if(!lz[lc[rt]]){ lz[rt]=lz[rc[rt]]; rz[rt]=rz[rc[rt]]; mx[rt]=mx[rc[rt]]; return; }
29 if(!lz[rc[rt]]){ lz[rt]=lz[lc[rt]]; rz[rt]=rz[lc[rt]]; mx[rt]=mx[lc[rt]]; return; }
30 int tmp=lz[rc[rt]]-rz[lc[rt]]-1;
31 mx[rt]=max(max(mx[lc[rt]],mx[rc[rt]]),tmp);
32 lz[rt]=lz[lc[rt]]?lz[lc[rt]]:lz[rc[rt]];
33 rz[rt]=rz[rc[rt]]?rz[rc[rt]]:rz[lc[rt]];
34 }
35 void update(int &rt,int l,int r,int pos){
36 if(!rt) rt=++tot;
37 if(l==r){ lz[rt]=rz[rt]=l; return; }
38 int mid=l+r>>1;
39 if(pos<=mid) update(lc[rt],l,mid,pos);
40 else update(rc[rt],mid+1,r,pos);
41 pushup(rt);
42 }
43 void merge(int &rt,int oth,int l,int r){
44 if(!rt){ rt=oth; return; }
45 if(l==r){
46 if(lz[oth]){
47 mx[rt]=0;
48 lz[rt]=rz[rt]=l;
49 }
50 return;
51 }
52 int mid=l+r>>1;
53 if(lz[lc[oth]]) merge(lc[rt],lc[oth],l,mid);
54 if(rz[rc[oth]]) merge(rc[rt],rc[oth],mid+1,r);
55 pushup(rt);
56 }
57 }s;
58 void dfs(int f,int st){
59 for(int i=head[st];i;i=nex[i]){
60 int v=to[i];
61 if(v==f) continue;
62 dfs(st,v);
63 s.merge(s.root[st],s.root[v],1,m);
64 }
65 int now=s.root[st];
66 if(!s.lz[now])ans[st]=-1;
67 else ans[st]=max(s.mx[now],m+s.lz[now]-1-s.rz[now]);
68 }
69 signed main(){
70 n=read(); m=read(); q=read();
71 for(int i=1;i<n;i++) add(read(),read());
72 for(int i=1;i<=q;i++){
73 int u=read(),v=read();
74 s.update(s.root[u],1,m,v);
75 }
76 dfs(0,1);
77 for(int i=1;i<=n;i++)
78 write(ans[i]), putchar('\n');
79 return 0;
80 }
T2
T3 Connect
状压全是神仙题。
题意稍微转化一下,不在$1\to n$链上的联通块与链上的点最多只能连一条边。
然后是永远想不到的状态定义:记$f_{s,i}$表示考虑点集为$s$,当前链的终点为$i$的最大留边边权。
有两种转移方式:一是在链的结尾新增一个单点作为新的结尾;二是在链的基础上加一个点集。
预处理出每个点集中的总边权和每个点集向某个单点连边的总边权进行转移。
巧妙的枚举状态$i$补集的子集的方法:
1 int anti=U^i;
2 for(int k=anti;k;k=(k-1)&anti)
$code:$


1 #include<bits/stdc++.h>
2 using namespace std;
3 const int NN=20;
4 int n,m,w[NN][NN],f[1<<NN][NN],U,sum[1<<NN],link[1<<NN][NN];
5 inline int read(){
6 int x=0,f=1; char ch=getchar();
7 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
8 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
9 return x*f;
10 }
11 inline void write(int x){
12 char ch[20]; int len=0;
13 if(x<0){ putchar('-'); x=~x+1; }
14 do{ ch[len++]=x%10+(1<<5)+(1<<4); x/=10; }while(x);
15 for(int i=len-1;i>=0;i--) putchar(ch[i]);
16 }
17 signed main(){
18 n=read(); m=read(); U=1<<n; U--;
19 for(int i=1;i<=m;i++){
20 int a=read(),b=read(),c=read();
21 w[a-1][b-1]=w[b-1][a-1]=c;
22 }
23 for(int i=1;i<=U;i++)
24 for(int j=0;j<n;j++) for(int k=0;k<j;k++)
25 if((i&(1<<j))&&(i&(1<<k))) sum[i]+=w[j][k];
26 for(int k=0;k<n;k++)
27 for(int i=1;i<=U;i++) for(int j=0;j<n;j++)
28 if(i&(1<<j)) link[i][k]+=w[j][k];
29 memset(f,-1,sizeof(f)); f[1][0]=0;
30 for(int i=1;i<=U;i++) for(int j=0;j<n;j++){
31 if(f[i][j]==-1) continue;
32 for(int k=0;k<n;k++)
33 if(w[j][k]&&!(i&(1<<k))) f[i|(1<<k)][k]=max(f[i|(1<<k)][k],f[i][j]+w[j][k]);
34 int anti=U^i;
35 for(int k=anti;k;k=(k-1)&anti)
36 f[i|k][j]=max(f[i|k][j],f[i][j]+sum[k]+link[k][j]);
37 }
38 write(sum[U]-f[U][n-1]); putchar('\n');
39 return 0;
40 }
T3
2021.8.8考试总结[NOIP模拟33]的更多相关文章
- 2021.9.17考试总结[NOIP模拟55]
有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...
- 2021.9.13考试总结[NOIP模拟52]
T1 路径 考虑每一位的贡献,第$i$位每$2^i$个数会变一次,那么答案为$\sum_{i=1}^{log_2n} \frac{n}{2^i}$. $code:$ 1 #include<bit ...
- 2021.8.11考试总结[NOIP模拟36]
T1 Dove玩扑克 考场并查集加树状数组加桶期望$65pts$实际$80pts$,考后多开个数组记哪些数出现过,只扫出现过的数就切了.用$set$维护可以把被删没的数去掉,更快. $code:$ 1 ...
- 2021.7.29考试总结[NOIP模拟27]
T1 牛半仙的妹子图 做法挺多的,可以最小生成树或者最短路,复杂度O(cq),c是颜色数. 我考场上想到了原来做过的一道题影子,就用了并查集,把边权排序后一个个插入,记录权值的前缀和,复杂度mlogm ...
- 2021.7.15考试总结[NOIP模拟16]
ZJ模拟D2就是NB.. T1 Star Way To Heaven 谁能想到这竟是个最小生成树呢?(T1挂分100的高人JYF就在我身边 把上边界和下边界看成一个点和星星跑最小生成树,从上边界开始跑 ...
- 2021.9.20考试总结[NOIP模拟57]
(换个编辑器代码就SB地不自动折叠了.. T1 2A 考察快读的写法. $code:$ T1 #include<bits/stdc++.h> #define scanf SCANF=sca ...
- 2021.9.14考试总结[NOIP模拟53]
T1 ZYB和售货机 容易发现把每个物品都买成$1$是没有影响的. 然后考虑最后一个物品的方案,如果从$f_i$向$i$连边,发现每个点有一个出度多个入度,可以先默认每个物品都能买且最大获利,这样可以 ...
- 2021.9.12考试总结[NOIP模拟51]
T1 茅山道术 仔细观察发现对于每个点只考虑它前面第一个与它颜色相同的点即可. 又仔细观察发现对一段区间染色后以这个区间内点为端点的区间不能染色. 于是对区间右端点而言,区间染色的贡献为遍历到区间左端 ...
- 2021.9.9考试总结[NOIP模拟50]
T1 第零题 神秘结论:从一个点满体力到另一个点的复活次数与倒过来相同. 于是预处理出每个点向上走第$2^i$个死亡点的位置,具体实现可以倍增或二分. 每次询问先从两个点同时向上倍增,都转到离$LCA ...
随机推荐
- ysoserial CommonsColletions3分析(2)
上篇文章讲到CC3的TransformedMap链,这篇我们就来讲一下LazyMap链. 其实LazyMap链还是使用的TemplatesImpl承载payload,InstantiateTransf ...
- find命令查找某一个时间点以后创建或者修改的文件
touch -t 201711211615.47 starttouch -t 201711211617.47 end find ./* -newer start |xargs ls -al-rw-r- ...
- Docker Command and Dockerfile
镜像相关命令 # 下载镜像 docker pull xxx # 搜素镜像 docker search xxx # 查看已经下载了哪些镜像 docker images # 查看已下载镜像的id dock ...
- 让PHP能够调用C的函数-FFI扩展
在大型公司中,一般会有很我编程语言的配合.比如说让 Java 来做微服务层,用 C++ 来进行底层运算,用 PHP 来做中间层,最后使用 JS 展现效果.这些语言间的配合大部分都是通过 RPC 来完成 ...
- Shell系列(1)- Shell概述
Shell是什么 Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动.挂起.停止甚至时编写一些程序 Shell还是一个功能 ...
- Linux系列(27) - 三剑客grep、awk、sed
Linux下一切皆文件,对Linux的操作就是对文件的处理 Linux中最重要的三个命令在业界被称为"三剑客",它们是awk,sed,grep 正则表达式就好比一个模版,这个模板就 ...
- jmeter5.2版本 配置元件之逻辑控制器详解
1.简单控制器(Simple Controller) 作用:将多个请求放置在一起,但是没有逻辑上的操作,进行一个简单的分组,一般是由于分组后的请求需要进行统一的某个操作或者存在共同的因素.在简单控制器 ...
- php pdo 参数绑定
* 数据表 -- MySQL dump 10.16 Distrib 10.1.31-MariaDB, for osx10.6 (i386) -- -- Host: localhost Database ...
- Fiddler修改抓包请求
hi,说到fiddler的用途,第一时间想到抓包,不过还有一个功能是:支持修改请求. 那么问题来了,怎么做呢?很简单,先定下我们需要修改哪个请求. 这里用F12跟fiddler做演示. 首先我们在F1 ...
- Python - Context Manager 上下文管理器
什么是上下文管理器 官方解释... 上下文管理器是一个对象 它定义了在执行 with 语句时要建立的运行时上下文 上下文管理器处理进入和退出所需的运行时上下文以执行代码块 上下文管理器通常使用 wit ...