\(\color{white}{\mathbb{名之以:海棠}}\)


考场 \(t1\) 看见题意非常简单,觉得可能是个简单题

暴力算出几个小样例右端点右移的时候左端点都是单调右移的,以为具有单调性,于是想了一系列维护单调性的方法,然而拍大样例的时候挂的很惨(又一次前一个半小时啥也没干)

看 \(t2\),时间不够了写了个 \(floyd\) 直接跳

\(t3\) 发现部分分很多,认真思考两个特殊点,一个小时找到了能得 \(50\) 分的做法

最后 \(t1\) 又加了个退火,在暴力能跑出来的范围内正确性还可以

出分发现 \(t1\) 捆绑测试所以 \(1\) 分也没骗到,\(t3\) 没考虑到逆序对可能很多没模爆了 \(long\) \(long\),又惨挂 \(35\)

这次难度分析再次出现重大失误,事实证明 \(t2\) 是最可做的

以后应该增加开题前思考分析时间,并且部分分也应进行对拍


A. 送花

首先当右端点右移时最优坐决策点不是单调的,因为加入一个数后可能使一个之前位置的贡献变小,那么原来依赖其贡献的最优区间可能左端点左移更优

线段树维护区间的贡献

对于右端点右移一位的时候,将这个值上上一个位置到上一个位置的值加当前贡献,上一个位置到这个位置的值减当前贡献,然后线段树维护区间最大值即可


B. 星空

首先是距离的转化,先把坐标系旋转45度

类似于曼哈顿转切比雪夫距离,这道题的距离是 \(min(|x_1-x_2|,|y_1-y_2|)\)

先处理出距离为零的,用并查集合并在一起,然后按 \(x\) 和 \(y\) 分别排序后找最近点对即可

对于方案数相当于距离和答案相等的边两端点并查集里 \(size\) 值的乘积

代码实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e5+5;
int n,xx,yy,fa[maxn],siz[maxn],ans=0x3f3f3f3f,ans1=0,cnt,tot;
pair<int,int>edge[maxn];
int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch)){
x=x*10+ch-48;
ch=getchar();
}
return x*f;
}
struct Node{
int x,y,id;
}p[maxn];
bool cmpx(Node a,Node b){
return a.x!=b.x?a.x<b.x:a.y<b.y;
}
bool cmpy(Node a,Node b){
return a.y!=b.y?a.y<b.y:a.x<b.x;
}
int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}
void merge(int x,int y){
x=find(x);
y=find(y);
if(x==y)return;
fa[x]=y;
siz[y]+=siz[x];
return ;
}
void add(int x,int y){
if(x>y)swap(x,y);
// cout<<x<<" "<<y<<endl;
edge[++cnt]=make_pair(x,y);
return ;
}
signed main(){
n=read();
for(int i=1;i<=n;i++){
xx=read();
yy=read();
p[i].x=xx+yy;
p[i].y=xx-yy;
fa[i]=i;
siz[i]=1;
p[i].id=i;
}
// for(int i=1;i<=n;i++){
// cout<<"ppp "<<p[i].x<<" "<<p[i].y<<endl;
// }
sort(p+1,p+n+1,cmpx);
for(int i=1;i<=n;i++){
int j=i+1;
while((p[j].x==p[i].x||p[j].y==p[i].y)&&j<=n){
merge(p[i].id,p[j].id);
j++;
}
if(j<=n)ans=min(ans,p[j].x-p[i].x);
}
// cout<<"hhh"<<endl;
sort(p+1,p+n+1,cmpy);
for(int i=1;i<=n;i++){
int j=i+1;
while((p[j].y==p[i].y||p[j].x==p[i].x)&&j<=n){
merge(p[i].id,p[j].id);
j++;
}
if(j<=n)ans=min(ans,p[j].y-p[i].y);
} for(int i=1;i<=n;i++){
int j=i+1;
while((p[j].y==p[i].y||p[j].x==p[i].x)&&j<=n){
j++;
}
if(j<=n&&p[j].y-p[i].y==ans)add(find(p[i].id),find(p[j].id));//cout<<"hhh "<<i<<" "<<j<<endl,
}
sort(p+1,p+n+1,cmpx);
for(int i=1;i<=n;i++){
int j=i+1;
while((p[j].x==p[i].x||p[j].y==p[i].y)&&j<=n){
j++;
}
if(j<=n&&p[j].x-p[i].x==ans)add(find(p[i].id),find(p[j].id));//cout<<"hhh "<<i<<" "<<j<<endl,
}
// for(int i=1;i<=n;i++){
// if(fa[i]==i)cout<<"hhh "<<i<<" "<<siz[i]<<endl;
// }
sort(edge+1,edge+cnt+1);
tot=unique(edge+1,edge+cnt+1)-edge-1;
for(int i=1;i<=tot;i++){
int x=edge[i].first;
int y=edge[i].second;
// cout<<"kkk "<<x<<" "<<y<<endl;
ans1+=siz[x]*siz[y];
}
cout<<ans<<endl<<ans1;
return 0;
}

C. 零一串

对于每个是 \(1\) 的位置处理一个长度为 \(T\) 的零一串,每一个是一的位置表示这一时刻这个 \(1\) 能不能左移,那么最终结果很容易能处理出来

考虑怎样从上一个位置转移过来:

对于第 \(i\) 个 \(1\) 如果可以在 \(j\) 的时刻左移,如果 \(i+1\) 个位置是紧邻的,那么它只能在 \(j+1\) 时刻左移,表达在 \(01\) 串上是右移一位

如果不紧邻,那么有几个 \(0\) 后面的可以移几次,相当于把 \(0!\) 串的前面几个 \(0\) 变成 \(1\)

发现只有首尾进行操作,用队列维护即可

对于第二问的答案,是在求每个 \(01\) 串第 \(i\) 的和

如果把矩阵拍在序列上,一定对应一段连续区间,用差分维护即可

代码实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
deque<int>q;
const int maxn=1e7+5;
const int mod=998244353;
char c[maxn];
int t,n,pos[maxn],cnt,all,dis[maxn],cf[maxn],sum[maxn],ans,num,ori;
bool ans1[maxn];
int po(int a,int b){
int ans=1;
while(b){
if(b&1)ans=1ll*ans*a%mod;
a=1ll*a*a%mod;
b>>=1;
}
return ans;
}
signed main(){
// freopen("shuju.in","r",stdin);
// freopen("my.out","w",stdout);
cin>>t;
scanf("%s",c+1);
n=strlen(c+1);
for(int i=1;i<=n;i++){
if(c[i]=='1')num++;
else ori+=num;
}
ori%=mod;
for(int i=1;i<=n;i++){
if(c[i]=='1')pos[++cnt]=i;
}
for(int i=1;i<=t;i++){
q.push_back(i);
}
for(int k=1;k<=cnt;k++){
all++;
if(q.back()+all>t&&q.size())q.pop_back();
q.push_front(1-all); for(int j=1;j<=pos[k]-pos[k-1]-1&&q.size();j++){
cf[q.front()+all]++;
cf[min(cnt-k+q.front()+all+1,t+1)]--;
q.pop_front();
} dis[k]=t-q.size();
ans1[pos[k]-dis[k]]=1;
}
for(int i=0;i<=t;i++){
if(i)sum[i]=(sum[i-1]+cf[i])%mod;
ori+=sum[i];
ori%=mod;
ans^=(po(233,i)*ori%mod);
}
for(int i=1;i<=n;i++)cout<<ans1[i];
cout<<endl<<ans;
return 0;
}

\(\color{white}{\mathbb{知否,知否,应是绿肥红瘦。}}\)

noip模拟40的更多相关文章

  1. 20190908 NOIP 模拟40

    考试过程: 刚看完题,发现T1是个类lis 问题,但要求$O(nlogn)$,应该是个数据结构优化dp,T2应该是个数据结构,T3是个字符串?没有匹配,不会是后缀数组吧,这是NOIP模拟啊,可能是个d ...

  2. Noip模拟40 2021.8.15

    T1 送花 按照题解意思说是扫描线题,但我觉得像一个线段树优化$dp$ 主要思想一样,就是暴力枚举右端点,同时维护左端点的最值, 考虑两种情况, 如果左端点在$r$扫到的数$i$上一次出现的位置之前, ...

  3. 2021.8.15考试总结[NOIP模拟40]

    T1 送花 线段树.枚举右端点,线段树记录左端点对应的值. 每次对当前颜色上上次出现的位置到上次出现的位置区间减,上次出现的位置到当前位置区间加. $code:$ 1 #include<bits ...

  4. NOIP模拟 40

    考得更嘛也不是了. 不过如果不犯任何低错的话.. T1 我神奇地想要缩减码量 比如想把尽量多的$b[i]-1$省掉 于是求$b[i]$的时候先减了个一 本来是正的 减完就忘了他应该是非负的了 于是线段 ...

  5. [考试总结]noip模拟40

    最近真的是爆炸啊... 到现在还是有不少没改出来.... 所以先写一下 \(T1\) 的题解.... 送花 我们移动右端点,之后我们用线段树维护全局最大值. 之后还要记录上次的位置和上上次的位置. 之 ...

  6. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  7. 11.7 NOIP模拟赛

    目录 2018.11.7 NOIP模拟 A 序列sequence(two pointers) B 锁lock(思路) C 正方形square(埃氏筛) 考试代码 B C 2018.11.7 NOIP模 ...

  8. NOIP模拟赛-2018.11.6

    NOIP模拟赛 今天想着反正高一高二都要考试,那么干脆跟着高二考吧,因为高二的比赛更有技术含量(我自己带的键盘放在这里). 今天考了一套英文题?发现阅读理解还是有一些困难的. T1:有$n$个点,$m ...

  9. 2016-06-19 NOIP模拟赛

          2016-06-19 NOIP模拟赛 by coolyangzc 共3道题目,时间3小时 题目名 高级打字机 不等数列 经营与开发 源文件 type.cpp/c/pas num.cpp/c ...

随机推荐

  1. IOS自动化测试环境搭建(Python & Java)

         一.前言 IOS的App自动化测试与Android的一样,也可以用appium来进行.但是IOS自动化依赖苹果的osx系统.Xcode构建等,且封闭的系统需要苹果开发者账号才可以驱动真机.A ...

  2. pwnable.kr之simple Login

    pwnable.kr之simple Login 懒了几天,一边看malloc.c的源码,一边看华庭的PDF.今天佛系做题,到pwnable.kr上打开了simple Login这道题,但是这道题个人觉 ...

  3. Bugku-misc 1-8题总结

    1.签到题 略过 2.这是一张单纯的图片 拉入winhex,在最后面有一段Uniocde编码,解码得到flag. 3.隐写 题目是隐写,binwalk打开分析 得到两个Zlib(提供数据压缩用的函式库 ...

  4. Linux - curl -w 参数详解

    -w 的作用 完成请求传输后,使 curl 在 stdout 上显示自定义信息 格式是一个字符串,可以包含纯文本和任意数量的变量 输出格式 输出格式中的变量会被 curl 用对应的值替换掉 所有变量的 ...

  5. shell脚本——awk

    目录 一.awk 1.1.awk简介 1.2.基本格式 1.3.工作原理 1.4.常见的内建变量(可直接用) 按字段输出文本 1.5.awk和getline 有重定向符 无重定向符 1.6.指定分隔符 ...

  6. 更换Swing界面中的窗口图标

    Swing 窗口图标更换 因为需要,所以要更改窗口的图标,很简单 在代码中加上 Image icon = Toolkit.getDefaultToolkit().getImage("图片地址 ...

  7. SQL injection : UNION attacks

    当应用程序易受SQL注入攻击并且查询结果在应用程序的响应中返回时,可以使用UNION关键字从数据库中的其他表检索数据.这将导致SQL注入联合攻击. UNION关键字允许您执行一个或多个附加的SELEC ...

  8. 一张图带你搞懂Node事件循环

    说一件重要的事儿:你还没关注公众号[前端印记],更多精彩内容等你探索-- 以下全文7000字,请在你思路清晰.精力充沛的时刻观看.保证你理解后很长时间忘不掉. Node事件循环 Node底层使用的语言 ...

  9. 01-ADB命令获取包名、界面名

    命令代码 adb shell dumpsys window |findstr mFocusedApp

  10. Dockerfile 多阶段构建实践

    写在前面 在Docker Engine 17.05 中引入了多阶段构建,以此降低构建复杂度,同时使缩小镜像尺寸更为简单.这篇小作文我们来学习一下如何编写实现多阶段构建的Dockerfile 关于doc ...