我们不是狼,我们只是长着獠牙的羊......

前言

我真 TM 爱死 \(\frac{1}{4}\) 了。

老实说,这套题是真恶心,第一题还有一点思路,到了后面是一点都搞不定了。

总的来说,主要原因是最近几天状态有些不好,需要及时调整。。

T1 u

解题思路

主要就是二维差分,对于一般的差分而言,都是以行和列进行差分。

由于这个题是一个直角三角形,因此我们需要改变一下差分的“方向”。

对于列和斜的方向进行差分(假设 1 数组为列方向的差分数组, 2 数组为斜着的),以下图为例。

当我们需要给黄色区域加上数时,先给 \((3.C)\) 位置的 1 加上,那我们就相当与给所有的有颜色的位置都加上了。

因此在 \((15,C)\) 位置的 1 减去就可以除去在蓝色以及绿色区域多加上的数。

接下来考虑如何除去橙色部分的影响,可以看作这个大的三角形减去绿色部分。

于是就可以给 \((3,D)\) 位置的 2 减去,给 \((15,P)\) 位置的 2 加上就好了。

code

#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch>'9'||ch<'0')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
const int N=1e3+10;
int n,m,ans,q1[N][N],q2[N][N];
void solve(int x,int y,int len,int num)
{
q1[x][y]+=num;
if(y+1<=n) q2[x][y+1]-=num;
if(x+len<=n)
{
q1[x+len][y]-=num;
if(y+len+1<=n)
q2[x+len][y+len+1]+=num;
}
}
signed main()
{
n=read();
m=read();
for(int i=1,x,y,len,num;i<=m;i++)
{
x=read();
y=read();
len=read();
num=read();
solve(x,y,len,num);
}
for(int i=1;i<=n;i++)
{
int num=0;
for(int j=1;j<=n;j++)
{
q1[i][j]+=q1[i-1][j];
q2[i][j]+=q2[i-1][j-1];
num+=q1[i][j]+q2[i][j];
ans^=num;
}
}
printf("%lld",ans);
return 0;
}

T2 v

解题思路

正解比较简单粗暴。。

其实就是记忆化状压暴搜,有一个需要注意的点就是对于比较小的用数组,大的用 map 这样可以大大缩小空间。

当然也可以“特判”过。。(不难发现当序列中白色和黑色数量相同时,并且操作数为 n 或者 n-1 的时候期望值一定是\(\dfrac{n}{2}\))

然后对于状压中去除第 i 位并且将它之后的向左移一位的操作有两种实现:

  1. (sta>>i<<i-1)|(sta&(1<<i-1)-1)
  2. (sta>>1&~((1<<i-1)-1))|(sta&(1<<i-1)-1)

然后,也就没啥好说的了。。。

code

#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch>'9'||ch<'0')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
const int N=35;
map<int,double> f[N];
int n,m,s;
string ch;
double dfs(int sta,int pos)
{
if(pos==n-m) return 0;
if(f[pos].find(sta)!=f[pos].end()) return f[pos][sta];
double sum=0;
for(int i=1;i<=pos/2;i++)
{
int clo1=(sta>>(i-1))&1,clo2=(sta>>(pos-i))&1;
int t1=(sta>>i<<i-1)|(sta&(1<<i-1)-1);
int t2=(sta>>(pos-i+1)<<pos-i)|(sta&((1<<pos-i)-1));
sum+=2*max(dfs(t1,pos-1)+clo1,dfs(t2,pos-1)+clo2);
}
if(pos&1)
{
int i=(pos+1)/2;
int clo=(sta>>(i-1))&1;
int temp=(sta>>1&~((1<<i-1)-1))|(sta&(1<<i-1)-1);
sum+=dfs(temp,pos-1)+clo;
}
sum=sum/(1.0*pos);
f[pos][sta]=sum;
return sum;
}
void check()
{
if(n&1||(m!=n-1&&m!=n))
return ;
int h=0,b=0;
for(int i=0;i<n;i++)
if(ch[i]=='W') b++;
else h++;
if(h!=b) return ;
printf("%.10lf",(double)n/2.0);
exit(0);
}
signed main()
{
n=read();
m=read();
cin>>ch;
check();
for(int i=1;i<=n;i++)
s=(s<<1)|(ch[i-1]=='W');
printf("%.20lf",dfs(s,n));
return 0;
}

T3 w

解题思路

树形 DP 设 f[i][1/0] 表示节点 i 是否与父亲连边。

设我们要翻转的边集为S,那么我们的最少的路径条数就是这个边集所能连接的点中度数为奇数的点的一半,

其实是那些可以配对为偶数的边都可以连成一条,所以只有奇数点才为路径的端点而且需要除以2

这样我们就会有一个状态了,状态中有两个量,一个是路径条数,一个是边的数量。

对于奇数点而言,其实就像相当与是好几对点,加上一个点,如果再加上一条边就不会增加操作次数。

偶数点也类似。对于 DP 方程的转移就好似 奇数+奇数=偶数 这一类的东西了。。。

code

#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch>'9'||ch<'0')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
const int N=1e5+10,M=N<<1,INF=1e9;
int n;
int tot,head[N],nxt[M],ver[M],edge[M];
struct Node
{
int opt,len;
Node friend operator + (Node x,Node y)
{
return (Node){x.opt+y.opt,x.len+y.len};
}
bool friend operator < (Node x,Node y)
{
if(x.opt!=y.opt)
return x.opt<y.opt;
return x.len<y.len;
}
}f[N][2];
void add_edge(int x,int y,int val)
{
ver[++tot]=y;
edge[tot]=val;
nxt[tot]=head[x];
head[x]=tot;
}
Node min(Node x,Node y)
{
if(x<y) return x;
return y;
}
void dfs(int x,int fa,int opt)
{
Node k1=(Node){INF,INF},k2=(Node){0,0};
for(int i=head[x];i;i=nxt[i])
{
int to=ver[i];
if(to==fa) continue;
dfs(to,x,edge[i]);
Node tmp1=min(k1+f[to][0],k2+f[to][1]);
Node tmp2=min(k1+f[to][1],k2+f[to][0]);
k1=tmp1;
k2=tmp2;
}
if(opt==1||opt==2) f[x][1]=min((Node){k1.opt,k1.len+1},(Node){k2.opt+1,k2.len+1});
else f[x][1]=(Node){INF,INF};
if(opt==0||opt==2) f[x][0]=min((Node){k1.opt+1,k1.len},k2);
else f[x][0]=(Node){INF,INF};
}
signed main()
{
n=read();
for(int i=1,x,y,c,d,temp;i<n;i++)
{
x=read();
y=read();
c=read();
d=read();
if(d==2) temp=2;
else temp=(c!=d);
add_edge(x,y,temp);
add_edge(y,x,temp);
}
dfs(1,0,2);
printf("%lld %lld",f[1][0].opt/2,f[1][0].len);
return 0;
}

7.18考试总结(NOIP模拟19)[u·v·w]的更多相关文章

  1. 8.18考试总结[NOIP模拟43]

    又挂了$80$ 好气哦,但要保持优雅.(草 T1 地衣体 小小的贪心:每次肯定从深度较小的点向深度较大的点转移更优. 模拟一下,把边按链接点的子树最大深度排序,发现实际上只有上一个遍历到的点是对当前考 ...

  2. [考试总结]noip模拟19

    连挂3场 \(\color{green}{\huge{\text{菜}}}\) 真 . 挂分王 ... 没什么好说的了,菜就是了. \(T1\) 一波手推想到了性质 \(1\),然后因为数组原因挂成比 ...

  3. 8.3考试总结(NOIP模拟19)[最长不下降子序列·完全背包问题·最近公共祖先]

    一定要保护自己的梦想,即使牺牲一切. 前言 把人给考没了... 看出来 T1 是一个周期性的东西了,先是打了一个暴力,想着打完 T2 T3 暴力就回来打.. 然后,就看着 T2 上头了,后来发现是看错 ...

  4. 2021.10.18考试总结[NOIP模拟76]

    T1 洛希极限 不难发现每个点肯定是被它上一行或上一列的点转移.可以预处理出每个点上一行,上一列最远的能转移到它的点,然后单调队列优化. 预处理稍显ex.可以用并查集维护一个链表,记录当前点之后第一个 ...

  5. 2021.9.18考试总结[NOIP模拟56]

    T1 爆零 贪心地想,肯定要先走完整个子树再走下一个,且要尽量晚地走深度大的叶子.所以对每个点的儿子以子树树高为关键字排序$DFS$即可. 也可$DP$. $code:$ T1 #include< ...

  6. NOIP 模拟 $19\; \rm v$

    题解 一道概率与期望的状压题目 这种最优性的题目,我们一般都是倒着转移,因为它的选择是随机的所以我们无法判断从左还是从右更有,所以我们都搜一遍 时间一定会爆,采用记忆化搜索,一种状态的答案一定是固定的 ...

  7. 6.17考试总结(NOIP模拟8)[星际旅行·砍树·超级树·求和]

    6.17考试总结(NOIP模拟8) 背景 考得不咋样,有一个非常遗憾的地方:最后一题少取膜了,\(100pts->40pts\),改了这么多年的错还是头一回看见以下的情景... T1星际旅行 前 ...

  8. 5.23考试总结(NOIP模拟2)

    5.23考试总结(NOIP模拟2) 洛谷题单 看第一题第一眼,不好打呀;看第一题样例又一眼,诶,我直接一手小阶乘走人 然后就急忙去干T2T3了 后来考完一看,只有\(T1\)骗到了\(15pts\)[ ...

  9. 5.22考试总结(NOIP模拟1)

    5.22考试总结(NOIP模拟1) 改题记录 T1 序列 题解 暴力思路很好想,分数也很好想\(QAQ\) (反正我只拿了5pts) 正解的话: 先用欧拉筛把1-n的素数筛出来 void get_Pr ...

  10. Noip模拟19(炸裂的开始) 2021.7.18

    T1 u 差分与前缀的综合练习. 分析数据范围,只能是在修改的时候$O(1)$做到,那么只能是像打标记一样处理那个三角形 正解是建立两个二位前缀和,一个控制竖向,一个控制斜向 每次在三角的左上,右下, ...

随机推荐

  1. c# semaphoreSlim限制线程数

    前言 我们在使用线程的时候,如果多个线程数去访问一个资源的时候,那么是非常影响程序的运行的,因为如果有写的操作,那么需要写锁,那么线程都会堵在同一个地方,那么我们可以限制一下访问一个资源的线程数. 正 ...

  2. FPGA技术脚本使用

    做fpga 不会脚本,基本跟残废一个概念.以前我觉得做FPGA应该学习什么人工智能,大数据,机器人.现在想起来真是傻逼,做fpga也好,做ic,做逻辑其实基本能力都是一样的. 一个学习tcl脚本,pe ...

  3. HarmonyOS NEXT应用开发—听歌识曲水波纹特效案例

    介绍 在很多应用中,会出现点击按钮出现水波纹的特效. 效果图预览 使用说明 进入页面,点击按钮,触发水波纹动画. 再次点击按钮,停止水波纹动画. 实现思路 本例涉及的关键特性和实现方案如下: 要实现存 ...

  4. HarmonyOS NEXT应用开发之深色模式适配

    介绍 本示例介绍在开发应用以适应深色模式时,对于深色和浅色模式的适配方案,采取了多种策略如下: 固定属性适配:对于部分组件的颜色属性,如背景色或字体颜色,若保持不变,可直接设定固定色值或引用固定的资源 ...

  5. 深度|为什么一定要从DevOps走向BizDevOps?

    简介: 为更好地厘清波涛汹涌的数字化转型浪潮下软件产业所面对的机遇与挑战,6月29日,阿里云云效与阿里云开发者评测局栏目,联合特邀了InfoQ极客帮副总裁付晓岩.南京大学软件工程学院教授张贺.Thou ...

  6. 阿里云峰会 | 阿里云CDN六大边缘安全能力,全力助推政企数字化转型

    6月9日,2020年阿里云线上峰会召开.阿里云智能总裁张建锋认为,数字化已经成为中国经济的主要驱动力,疫情让政府.企业都认识到数字化的迫切性.在峰会上,阿里云CDN正式对外发布基于CDN构建的六大边缘 ...

  7. [FAQ] "cannot refer to unexported name" in Golang ?

    Golang 项目中如果使用了其它模块中找不到的函数.常量等,都会提示 "cannot refer to unexported name". 遇到这种情况,要么是拼写错误了,要么是 ...

  8. 每天5分钟复习OpenStack(十三)存储缓存技术Bcache

    Ceph作为一个分布式存储,在项目中常见的形态有两者,一种是采用 SSD 或NVME 磁盘做Ceph的日志盘,使用SATA磁盘来做数据盘.这样的好处是比较经济实惠.另一种则是全部采用 SSD 或NVM ...

  9. dotnet 警惕 async void 线程顶层异常

    在应用程序设计里面,不单是 dotnet 应用程序,绝大部分都会遵循让应用在出现未处理异常状态时终结的原则.在 dotnet 应用里面,如果一个线程顶层出现未捕获异常,则应用进程将会被认为出现异常状态 ...

  10. GeoHash实现附近的人功能(如微信附近的人、共享单车附近的车辆、美团附近的商家)

    如何查找当前点(118.818747°E,32.074497°N)附近500米的人? 这一类功能很常见(如微信附近的人.共享单车附近的车辆.美团附近的商家),那在java中是如何实 现的呢? 1 实现 ...