题解:USACO23OPEN-Silver

T1 Milk Sum

给定一个长度为 \(N\) 的序列 \(a_1,a_2,...,a_n\),现在给出 \(Q\) 次操作每次将 \(a_x\) 修改为 \(y\) , 每次修改后,求将序列重排后的 \(T\) 的最大值,定义 \(T=\sum_{i=1}^{n}i \times a_i)\)

每次修改数组后会将序列还原成原样(修改不继承)

有一个显然的结论:对于\(\forall 0<a<b, 0<c<d\) ,满足\(a*c+b*d>a*d+b*c\)

所以将序列从小到大排序得到的 \(T\) 一定更大

所以预先把排好的原序列存下来,对于每次修改只需要二分出修改后应放的位置,然后(1)减掉原来数的贡献,(2)加上现在数的贡献,(3)所有位置后挪1或前挪1的贡献变化

注意二分后查询时的细节(加1减1)。

#include<bits/stdc++.h>
#define F(i,l,r) for(int i=l;i<=r;++i)
#define G(i,r,l) for(int i=r;i>=l;--i)
#define ll long long
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
char buf[100],*p1=buf,*p2=buf;
inline int gc(){ return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100,stdin),p1==p2)?EOF:*p1++; }
inline int rd(){
int x=0; char ch=gc(); bool f=1;
while(!isdigit(ch)) f^=(ch=='-'),ch=gc();
while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=gc();
return f?x:-x;
}
const int N=2e5+5;
ll sum[N],tot=0,a[N],b[N],n,q,x,y;
int main(){
// freopen("a.in","r",stdin);freopen("a.out","w",stdout);
n=rd(); F(i,1,n) a[i]=rd(),b[i]=a[i]; sort(b+1,b+n+1);
F(i,1,n) tot+=b[i]*i,sum[i]=sum[i-1]+b[i];
q=rd(); while(q--){
x=rd(),y=rd();
int u=upper_bound(b+1,b+n+1,y)-b,v=lower_bound(b+1,b+n+1,a[x])-b;
if(v>=u) printf("%lld\n",tot-v*a[x]+u*y+sum[v-1]-sum[u-1]);
else printf("%lld\n",tot-v*a[x]+(u-1)*y+sum[v]-sum[u-1]);
}
return 0;
}

T2 Field Day

(又是逆向思维题...)

给出 \(N\) 个长度为 \(C\) 的 \(GH\) 串,将 \(G\) 看作 \(0\) ,将 \(H\) 看作 \(1\) , 则每个串可看做01串,对于每个 \(i\) ,求 \(max_{j=1}^{n} popcount(a_i \oplus a_j)\)

\(2 \leq N \leq 10^5,1 \leq C \leq 18\)

暴力是 \(O(N^2)\) 的,发现本题的特点如下:

(1) \(C\) 很小,算一下本质不同的 \(01\) 串只有 \(2^{18}\) 个,大概是25万多一点。

※(2)最大值不是很好求,考虑倒过来想,转化成求最小值。

(3)与串 \(a_i\) 差异度为 \(k\) 的一个串 \(t\) 可以看做是 将 \(a_i\) 的其中 \(k\) 个数一步一步取反后得到的。

一个数可以由多个给出的串通过这样的取反变化得到,但我们只关心至少要改变几个数位才能得到 \(t\)(求最小值嘛),所以如果我们能找到一种操作顺序,使第一次得到 \(t\) 花的就是最少步数的话,那\(0-2^c-1\) 下的每个数都只需要访问一遍就可以了!

什么样的操作顺序使我们需要的呢?灵光一现,考虑广搜,先搜出每个串改1个数位能得到的结果,再考虑改2个数,再改3个,4个....一直到 \(c\) 个,每次都把上一层更新出的数存下来用于下一层更新,访问过的数不再重复访问,时间复杂度 \(O(2^C)\)。

广搜写法:

#include<cstdio>
#include<queue>
using namespace std;
#define ri register int
#define F(i,l,r) for(ri i=l;i<=r;++i)
const int N=1e5+5;
queue<int> q;
int c,n,a[N],f[(1<<18)+100];
char s[22];
bool vis[(1<<18)+100];
int main(){
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
scanf("%d%d",&c,&n);
F(i,1,n){
scanf("%s",s+1);
int sum=0;
F(j,1,c) sum=(sum<<1)+(s[j]=='G');
a[i]=sum; q.push(sum); vis[sum]=1;
}
while(q.size()){
int x=q.front();q.pop();
F(i,1,c){
int y=x^(1<<(i-1));
if(vis[y] || f[y]) continue;
f[y]=f[x]+1;
vis[y]=1; q.push(y);
}
}
F(i,1,n) printf("%d\n",c-f[(1<<c)-1-a[i]]);
return 0;
}

用循环模拟广搜:

#include<cstdio>
using namespace std;
#define ri register int
#define F(i,l,r) for(ri i=l;i<=r;++i)
#define min(x,y) x<y?x:y
const int N=1e5+5;
int sum,c,n,a[N],f[(1<<18)+100];
char s[22];
int main(){
freopen("b.in","r",stdin); freopen("b.out","w",stdout);
scanf("%d%d",&c,&n);
F(i,0,(1<<c)-1) f[i]=99999999;
F(i,1,n){
scanf("%s",s+1);
sum=0;
F(j,1,c) sum=(sum<<1)+(s[j]=='G');
f[sum]=0;
a[i]=sum;
}
F(i,1,c) F(j,0,(1<<c)-1) f[j^(1<<i-1)]=min(f[j^(1<<i-1)],f[j]+1);
F(i,1,n) printf("%d\n",c-f[(1<<c)-1-a[i]]);
return 0;
}

结合两种方法而观之,发现循环其实是dp,广搜其实是记搜...

好好好万物皆可dp是吧

T3 Pareidolia

给定一个仅包含小写字母的字符串 \(s\) , 长度不超过 \(3 \times 10^5\)。

定义函数 \(B(s)\) 表示把 \(s\) 中的若干个字母删去后,形成尽量多个bessie相连的形式(bessiebessiebessie...),返回bessie的最大数量。

如 \(B(\text{"bqessiyexbesszieb"})=2\)。

求 \(s\) 的所有子串的 \(B\) 函数之和。

两个误区:

(1)一个字符最多只能存在于一个bessie中而非多个。还担心会不会一匹配多,把问题想复杂了

(2)审题不清:没发现任意字母都可以删去,还以为是KMP,写到最后再读题发现问题之后哭死,只剩不到1h,直接失去继续写下去的动力了。。。(想好再下笔!!!)

对我来说,光是如何简明地书写判断是否找到了一个新的bessie都有难度。。。

由于模式串是固定的而且只有六位,直接对于 b,e,s,i这几种字符记录我所在的bessie串的开头b所在的位置即可。开头记录下来,串的位置当然也就确定啦!而且后面统计答案还要用到

考虑新发现一个bessie串对答案的贡献。记 \(f_i\) 为以i结尾的所有子串的B函数之和,\(pos\) 为新发现的bessie串的开头位置。则有

\[f_i=f_{pos-1}+pos
\]

emm...可以感性理解为:继承没发现这个串之前的答案 + 起点为1-pos,终点固定成i的所有串都会多看到当前这个新串。

最终答案 \(sum=\sum_{i=1}^{n} f_i\)

注意有些字符的更新是有顺序的,不要写挂了。

#include<cstdio>
const int N=3e5+5;
char s[N];
int p[10];
long long f[N],sum=0;
int main(){
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
scanf("%s",s+1);
for(int i=1;s[i];++i){
// F(i,1,6) printf("%d ",p[i]); puts("");
if(s[i]=='b') p[1]=i;
else if(s[i]=='e') p[2]=p[1],p[6]=p[5];
else if(s[i]=='s') p[4]=p[3],p[3]=p[2];//不能写反,否则一个's'会同时更新p[4],p[3]
else if(s[i]=='i') p[5]=p[4];
if(p[6]) f[i]=f[p[6]-1]+p[6];
//f[i]:以i结尾的所有子串的B函数之和
//p[6]:以i结尾的能含有当前这个新增bessie的子串的数量
//p[6]位置以前的所有串还能多包含一个bessie(即当前新增的这个),所以要+f[p[6]-1]
sum+=f[i];
} printf("%lld",sum);
return 0;
}

存疑:为什么下面这种写法是错的???

#include<bits/stdc++.h>
using namespace std;
char c[300005];
unsigned long long p[10];
int main(){
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
scanf("%s",c+1);
unsigned long long lenc=strlen(c+1);
unsigned long long ans=0;
unsigned long long sum=0;
for(unsigned long long i=1;i<=lenc;i++){
if(c[i]=='b') p[1]=i;
if(c[i]=='e'){
p[2]=p[1];
if(p[5]!=p[6]) sum+=p[5];
p[6]=p[5];
}
if(c[i]=='s') p[4]=p[3],p[3]=p[2];
if(c[i]=='i') p[5]=p[4];
ans+=sum;
}
printf("%llu",ans);
return 0;
}

模拟赛总结:

1.感觉T1写了近两个小时有点慢了,如果把找 \(a_x\) 原位置直接也写成lower_bound可能会节省很多时间(毕竟每写一个二分查总是要调很久...)

2.T2部分分拿的还是很稳的,但对于C较小这个性质的运用还是差了些:只想到了用bitset优化异或过程。还有,积累逆向思维的经验:原问题不好想,那就承认它不好想,就大胆考虑倒过来想

(由于正着做不好想,所以我们考虑倒过来想)

3.T3首先审题不清(想好再下笔),第二想复杂了,被吓到了(还是要多手玩几个样例去自己体会题目的要求,不要偷懒 ~ ~ ~)

写在最后:距离NOIP2023仅剩16天,耳边又想起了中考前我的语文老师告诉我的那句话,

“行百里者半九十。”

希望不留遗憾~加油NOIP2023!

题解:USACO23OPEN-Silver的更多相关文章

  1. 洛谷 P1821 [USACO07FEB]银牛派对Silver Cow Party 题解

    P1821 [USACO07FEB]银牛派对Silver Cow Party 题目描述 One cow from each of N farms (1 ≤ N ≤ 1000) conveniently ...

  2. usaco silver刷水~其实是回顾一下,补题解

    [BZOJ1606][Usaco2008 Dec]Hay For Sale 裸01背包 ;i<=n;i++) for(int j=m;j>=a[i];j--) f[j]=max(f[j], ...

  3. POJ 3268 Silver Cow Party(最短路&Dijkstra)题解

    题意:有n个地点,有m条路,问从所有点走到指定点x再走回去的最短路中的最长路径 思路:用Floyd超时的,这里用的Dijkstra. Dijkstra感觉和Prim和Kruskal的思路很像啊.我们把 ...

  4. 【luogu P1821 [USACO07FEB]银牛派对Silver Cow Party】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1821 反向多存一个图,暴力跑两遍 #include <cstdio> #include < ...

  5. USACO 2013 Nov Silver Pogo-Cow

    最近因为闲的蛋疼(停课了),所以开始做一些 USACO 的银组题.被完虐啊 TAT 貌似 Pogo-Cow 这题是 2013 Nov Silver 唯一一道可说的题目? Pogo-Cow Descri ...

  6. POJ 3268 Silver Cow Party (最短路dijkstra)

    Silver Cow Party 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/D Description One cow fr ...

  7. poj 3268 Silver Cow Party(最短路)

    Silver Cow Party Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17017   Accepted: 7767 ...

  8. 1675: [Usaco2005 Feb]Rigging the Bovine Election 竞选划区(题解第二弹)

    1675: [Usaco2005 Feb]Rigging the Bovine Election 竞选划区 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit:  ...

  9. 1675: [Usaco2005 Feb]Rigging the Bovine Election 竞选划区(题解第一弹)

    1675: [Usaco2005 Feb]Rigging the Bovine Election 竞选划区 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit:  ...

  10. POJ 3268 Silver Cow Party 最短路径+矩阵转换

    Silver Cow Party Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other) T ...

随机推荐

  1. VisionOn:新一代在线制图工具,简单易用又高颜值

    Vision On 一款集流程图.思维导图.白板于一体的轻量级在线图形工具 在工作和学习过程中,通过可视化的图形,有助于清晰高效地表达我们的灵感.想法.思想. 工欲善其事,必先利其器. 目前,思维导图 ...

  2. SpringBoot整合RabbitMQ 通俗易懂 超详细 【内含案例】

    SpringBoot结合RabbitMq SpringBoot 框架部署 HelloWorld 简单模式 Topic 通配符模式 一.SpringBoot 框架部署 1.创建Maven工程(我用的ID ...

  3. 仅花一天时间,开发者重制 32 年前经典 Mac 应用!

    导读:在这个快节奏的技术世界里,重温过去并从中汲取灵感总是一件有趣的事情.今天要介绍的是一款仅用一天时间重制的经典 Macintosh 应用--Stapler.这款应用最初发布于1992年,现在由一位 ...

  4. 平衡树 -- Splay & Treap

    Treap & Splay学习笔记 前置知识 -- BST 二叉搜索树,一种比较好玩的数据结构,其实现原理是运用每个点的权值构建,其中满足这样的构造方式: 若 \(value > t[x ...

  5. C#应用 - 破解注入外挂必备神器Harmony

    目录 前言 1,快速开始 1.1 SomeGameClass类 1.2 Patch01类 1.3 MyPatcher类 1.4 跑起来 2,破解 2.1 类库项目 2.2 winform项目 3,注入 ...

  6. Shell 避免无限递归

    在编写 Shell 脚本时,有时会产生我们不期望的递归. 比如说,我曾经写过一个脚本,名为 foo.sh. foo.sh 的内容如下: function foo { # TODO } foo 然后我在 ...

  7. 千牛hook 旺旺hook,旺旺发消息call,千牛发消息call,千牛机器人,破解旺旺发消息代码,破解千牛发消息代码,反汇编旺旺发消息,反汇编千牛发消息,旺旺发消息组件,千牛发消息组件

    由于工作需要,做了相关的编码,有demo,拿去后,直接按demo写代码即可实现千牛发消息,非常稳定.非反汇编找call,基本不怕千牛升级,原理是基于千牛架构做出来的,除非千牛改架构,已稳定使用2年,未 ...

  8. sicp每日一题[1.44]

    Exercise 1.44 The idea of smoothing a function is an important concept in signal processing. If f is ...

  9. C++17: 用折叠表达式实现一个IsAllTrue函数

    前言 让我们实现一个 IsAllTrue 函数,支持变长参数,可传入多个表达式,必须全部计算为true,该函数才返回true. 本文记录了逐步实现与优化该函数的思维链,用到了以下现代C++新特性知识, ...

  10. 原生JavaScript实现可旋转立方体效果基础示例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...