Noip模拟19(炸裂的开始) 2021.7.18
T1 u
差分与前缀的综合练习。
分析数据范围,只能是在修改的时候$O(1)$做到,那么只能是像打标记一样处理那个三角形
正解是建立两个二位前缀和,一个控制竖向,一个控制斜向
每次在三角的左上,右下,左下几个位置分别打上加一或者减一的标记
之后$N^2$查询时直接将标记“下放”就可以求出正确的异或和
思路挺神的
知识点
差分与前缀
标记下放
1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 inline int read(){
5 int x=0,f=1; char ch=getchar();
6 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
7 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
8 return x*f;
9 }
10 const int NN=4005;
11 int n,q;
12 int d1[NN][NN],d2[NN][NN];
13 namespace WSN{
14 inline int main(){
15 n=read(); q=read();
16 while(q--){
17 int r=read(),c=read(),l=read(),s=read();
18 d1[r][c]+=s;
19 d1[r+l][c]-=s;
20 d2[r][c+1]-=s;
21 d2[r+l][c+l+1]+=s;
22 }
23 int ans=0,tmp=0;
24 for(int i=1;i<=n;i++){
25 tmp=0;
26 for(int j=1;j<=n;j++){
27 tmp+=d1[i][j]+d2[i][j];
28 d1[i+1][j]+=d1[i][j];
29 d2[i+1][j+1]+=d2[i][j];
30 ans^=tmp;
31 }
32 }
33 printf("%lld\n",ans);
34 return 0;
35 }
36 }
37 signed main(){return WSN::main();}
T2 v
一看数据范围,就是知道是个状压,但是根本不懂如何定义数组。。
更何况还有一个后效性的问题。。。
但是如果足够暴力的将每一种可能的删球情况都枚举出来的话,就没事了
那么肯定会T,考虑记忆化搜索
我们设$m[sta]$表示在$sta$状态下的期望值
因为在进行$dfs$时状态会重复,考虑使用哈希表去重
然后就是在进行状压时候的状态转移,比较神
大概就是:
1 将数列向右移动几位
2 将数列往回移动那么多位-1,相当于去掉了一位
3 将原来数列里面的后几位提取过来,给那个位移了的数列拼起来
知识点:
记忆化搜索
状压dp
哈希表
1 #include<bits/stdc++.h>
2 using namespace std;
3 int n,k;char ch[35];
4 struct HASH{
5 struct edge{int to,next;};edge e[50000013];int head[50000013],tot; short leng[50000013],len; double val[50000013];
6 double &operator[](int sta){
7 int x=sta*len%50000013;
8 for(int i=head[x];i;i=e[i].next) if(e[i].to==sta&&leng[i]==len) return val[i];
9 e[++tot]=(edge){sta,head[x]}; leng[tot]=len; head[x]=tot; return val[tot]=-1.0;
10 }
11 }m;
12 inline double dp(int len,int sta){
13 // cout<<len<<endl;
14 if(len==n-k) return 0.0;
15 m.len=len; if(m[sta]>-0.5) return m[sta];//在返回记忆化值之前记录长度,否则会出现后效性
16 m[sta]=0;//记得定义初始状态值,否则样例返回-0.0(因为原本不定义初始值m[sta]为-1,减一后正好为-0.0)
17 int pos[35],st=sta;
18 for(int i=1;i<=len;i++) pos[i]=st&1,st>>=1;//复制原状态到数组备用(是反着赋值)
19 for(int i=1;i<=len/2;i++){
20 int st1=sta>>len-i+1<<len-i|sta&(1<<len-i)-1;//从左面删除
21 int j=len-i+1;
22 int st2=sta>>len-j+1<<len-j|sta&(1<<len-j)-1;//从右面删除
23 double ans1=dp(len-1,st1)+pos[j];
24 double ans2=dp(len-1,st2)+pos[i];
25 m.len=len; m[sta]+=2.0/len*max(ans1,ans2);
26 }
27 if(len&1){//如果是奇数就判断中间之前没有循环到的一位
28 int mid=len/2+1;
29 int st3=sta>>len-mid+1<<len-mid|sta&(1<<len-mid)-1;
30 double ans3=dp(len-1,st3)+pos[mid];
31 m.len=len; m[sta]+=1.0/len*ans3;
32 }
33 return m[sta];
34 }
35 namespace WSN{
36 inline int main(){
37 scanf("%d%d%s",&n,&k,ch+1); int sta=0;
38 for(int i=1;i<=n;i++) sta=sta<<1|(ch[i]=='W');
39 printf("%.10lf",dp(n,sta));
40 return 0;
41 }
42 }
43 signed main(){return WSN::main();}
T3 w
第一眼,可恶,又是$dp$。。
树形$dp$当时学的比较糟糕(不过假期讲课skyh大神讲过后明白了许多)
这题有两个难点
一个是关于状态的定义,
我们发现可以把c,d$xor$表示这个边是否需要反转
考虑最小操作次数,其实就是度数为奇数的点数/2,这里的度数指的是所连的最终状态与之前不一样的边数,包括必须翻和不必须。
那么我们开一个结构体记录度数为奇数的点数和链的长度,结构题数组$dp_{i,0/1}$表示$i$上面的一条边反转与否,并记录儿子的信息
第二个是分类讨论,
如果度数为奇,
度数为奇的儿子不用翻,之前是偶数儿子用翻取min
如果度数为偶,
度数为偶的儿子用翻,之前是偶数儿子不用翻取min
统计完儿子的信息就要把自己加进子树中。
如果当前点和父亲必须翻,为自己是奇数的个数,长度+1和自己是偶数的个数+1,长度+1取min。
如果当前点和父亲必须不翻,为自己是奇数的个数+1,长度和自己是偶数的个数,长度。
如果可翻可不翻,那么两种状态都会存在。
转移的时候使用中间量$w_1,w_2,n_1,n_2$1表示奇度数的转移信息,2同理表示偶数的
1 #include<bits/stdc++.h>
2 using namespace std;
3 const int NN=1e5+5,inf=0x3f3f3f3f;
4 int n;
5 struct SNOW{int to,next,c;};SNOW e[NN<<1]; int head[NN],rp;
6 struct DP{
7 int sum,len;
8 DP(){}
9 DP(int x,int y){this->sum=x; this->len=y;}
10 DP operator+(DP x) const{
11 DP ans;
12 ans.len=len+x.len;
13 ans.sum=sum+x.sum;
14 return ans;
15 }
16 bool operator<(DP x) const{
17 return sum==x.sum? len<x.len : sum<x.sum;
18 }
19 }dp[NN][3];
20 inline void add(int x,int y,int z,int w){
21 e[++rp].to=y; e[rp].next=head[x]; e[rp].c=(w==2?2:z^w); head[x]=rp;
22 e[++rp].to=x; e[rp].next=head[y]; e[rp].c=(w==2?2:z^w); head[y]=rp;
23 }
24 inline void dfs(int f,int x,int opt){
25 DP w1=DP(inf,inf);
26 DP w2=DP(0,0);
27 for(int i=head[x];i;i=e[i].next){
28 int y=e[i].to;
29 if(y==f) continue;
30 dfs(x,y,e[i].c);
31 DP n1=min(w2+dp[y][1],w1+dp[y][0]);
32 DP n2=min(w1+dp[y][1],w2+dp[y][0]);
33 w1=n1; w2=n2;
34 }
35 if(opt==0){
36 dp[x][1]=DP(inf,inf);
37 dp[x][0]=min(DP(w1.sum+1,w1.len),w2);
38 }
39 else if(opt==1){
40 dp[x][1]=min(DP(w2.sum+1,w2.len+1),DP(w1.sum,w1.len+1));
41 dp[x][0]=DP(inf,inf);
42 }
43 else{
44 dp[x][1]=min(DP(w2.sum+1,w2.len+1),DP(w1.sum,w1.len+1));
45 dp[x][0]=min(DP(w1.sum+1,w1.len),w2);
46 }
47 }
48 namespace WSN{
49 inline int main(){
50 scanf("%d",&n);
51 for(int i=1,a,b,c,d;i<n;i++) scanf("%d%d%d%d",&a,&b,&c,&d),add(a,b,c,d);
52 dfs(0,1,0); printf("%d %d\n",dp[1][0].sum/2,dp[1][0].len);
53 return 0;
54 }
55 }
56 signed main(){return WSN::main();}
Noip模拟19(炸裂的开始) 2021.7.18的更多相关文章
- NOIP模拟 19
最近试考的脑壳疼 晚上还有一场555 T1 count 研究性质题. 研究好了AC,研究不明白就没头绪 首先枚举n的因子d 其次发现因为是树,所以如果合法,贡献只能是1 然后发现如果合法,一定是一棵一 ...
- NOIP 模拟19
考试状态一次不如一次,所以这次.......我经无言以对 考完试T1就A了,但不是考试时A的,所以屁用没有! 这次考试其实T1想的是正解但是自己傻逼了,感觉自己只能拿部分分,(而且我还把数据范围少看一 ...
- [考试总结]noip模拟19
连挂3场 \(\color{green}{\huge{\text{菜}}}\) 真 . 挂分王 ... 没什么好说的了,菜就是了. \(T1\) 一波手推想到了性质 \(1\),然后因为数组原因挂成比 ...
- 8.3考试总结(NOIP模拟19)[最长不下降子序列·完全背包问题·最近公共祖先]
一定要保护自己的梦想,即使牺牲一切. 前言 把人给考没了... 看出来 T1 是一个周期性的东西了,先是打了一个暴力,想着打完 T2 T3 暴力就回来打.. 然后,就看着 T2 上头了,后来发现是看错 ...
- NOIP 模拟 $19\; \rm w$
题解 \(by\;zj\varphi\) 树形 \(dp\) 题目 有一个结论:对于一个图,有多少奇度数的点,处以二就是答案,奇度数指的是和它相连的边中被反转的是奇数 证明很好证 那么设 \(dp_{ ...
- NOIP 模拟 $19\; \rm v$
题解 一道概率与期望的状压题目 这种最优性的题目,我们一般都是倒着转移,因为它的选择是随机的所以我们无法判断从左还是从右更有,所以我们都搜一遍 时间一定会爆,采用记忆化搜索,一种状态的答案一定是固定的 ...
- NOIP 模拟 $19\; \rm u$
题解 \(by\;zj\varphi\) 二维差分的题目 维护两个标记,一个向下传,一个向右下传: 对于每次更新,我们可以直接更新 \((r,c)+s,(r+l,c)-s\) ; \((r,c+1)- ...
- noip模拟19/20
这两场考试大部分的题都考过,然鹅有的 \(trick\) 忘了,有的当时咕了(虽然现在还咕着) 首先是 \(v\) 这道题需要加一个小优化,对于较小的状态应该直接用数组记录,较大的再用 map 记 然 ...
- 2021.9.17考试总结[NOIP模拟55]
有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...
随机推荐
- L2TP协议简介
传送门:L2TP代码实现 1. L2TP 概述 L2TP(Layer 2 Tunneling Protocol,二层隧道协议)是 VPDN(Virtual Private Dial-up Networ ...
- uniapp获取用户OpenId及用户详情
页面增加一个按钮 <button type="default" open-type="getUserInfo" @click="getUserI ...
- python库--pandas--文本文件读取
.read_table() / read_csv() filepath_or_buffer 文件路径 sep='\t' 分隔符. 设置为N, 将尝试自动确定 delimiter=N sep的备 ...
- git换行符自动转换导致整个文件被修改的解决方案
不少开发者可能遇到过这个问题:从git上拉取服务端代码,然后只修改了一处地方,准备提交时,用diff软件查看,却发现整个文件都被修改了.这是git自动转换换行符导致的问题. 原因 不同操作系统使用的换 ...
- Set代码
现有一整数集(允许有重复元素),初始为空.我们定义如下操作:add x 把 x 加入集合del x 把集合中所有与 x 相等的元素删除ask x 对集合中元素x的情况询问 对每种操作,我们要求进行如下 ...
- Django学习day12随堂笔记
每日测验 """ 1.什么是cookie和session,你能描述一下它们的由来和工作机制吗(切勿糊弄,敷衍了事) 2.django中如何操作cookie和session ...
- 【PHP数据结构】PHP数据结构及算法总结
断断续续地把这个系列写完了,就像上一个设计模式一样,算法这个系列也是前前后后写了将近有一年的时间.当然,都是在业余或者晚上的时间写完的,所以进度如此地慢.更主要的是,既然要写,总得要自己先弄懂吧,对于 ...
- mysql5.7当两个字段名类似,查询时会出错
excepInfo: select id,describe from iwebshop_student_problem where id=256 order by id desc -- You hav ...
- Wannafly挑战赛10F-小H和遗迹【Trie,树状数组】
正题 题目链接:https://ac.nowcoder.com/acm/contest/72/F 题目大意 \(n\)个字符串,包括小写字母和\(\#\).其中\(\#\)可以替换为任意字符串.求有多 ...
- P5404-[CTS2019]重复【KMP,dp】
正题 题目链接:https://www.luogu.com.cn/problem/P5404 题目大意 给出一个字符串\(S\),然后求有多少个长度为\(m\)的串\(T\)满足.无限多个串\(T\) ...