trash ,但不完全是trash

t 1 t1 t1考了一个神奇的结论还没有证明, t 2 t2 t2玩了一些复杂度的花样, t 3 t3 t3稍微阳间一点,是一个并不复杂的容斥,如果放在 t 1 t1 t1可能更合适一些, t 4 t4 t4就是在原题的基础上改了一下然后就成了一道毒瘤数据结构题,

t 1 t1 t1总之感觉还是出的很烂,所以就不管它了

t 2 t2 t2暴力能过,很显然留在最后补

t 3 t3 t3赛时过了,那没什么了

所以只要胡一下 t 4 t4 t4就好是吗

补数据结构题是最痛苦的

最小生成树

首先有一道原题:[HNOI2010]城市建设 ,于是你不需要用这道题的任何性质就可以得到 80 p t s 80pts 80pts。

这就是场上的最优解了,毕竟正解的思路非常人能及,而且也就少了 20 p t s 20pts 20pts而已,不过唯一的缺点是码量有点大

不过正解的话从链入手似乎非常合理,但是只有 40 p t s 40pts 40pts,最后的数据结构维护还是非常难想,所以这道题的性价比真的不高啊

对于链的情况,可以看成是 [ 1 , n ] [1,n] [1,n]的若干不相交区间 [ l i , r i ] [l_i,r_i] [li​,ri​]通过与 0 0 0节点连边从而联通,因此在用线段树维护区间信息时,只用处理中间两个连通块。如果都不与 0 0 0联通,那么不合法;如果都与 0 0 0联通,不需要花费代价就可以合并,如果只有一边与 0 0 0联通,那么需要花费中间那条二类边的代价。结合画图不难理解。

搞清楚链的情况后,我们就有了 40 p t s 40pts 40pts 好少啊,考场上思考数据结构完全没有动力啊

推广到一般情况,我们只需要一步:求出一棵树对应的等效链 。这看起来非常不可思议,但是如果你把两棵树合并看成两条链合并,然后套用链的维护方式就不难理解了。

这个地方很容易给人一个误解,就是直接将结论扩展好像可以一步到位。

事实上,我们还需要下一个结论:假设当前加的边是 u , v u,v u,v,其分属于连通块 S S S, T T T,那么我们可以把 u , v u,v u,v这条边等效成任意 u ′ ∈ S , v ′ ∈ T u'\in S,v'\in T u′∈S,v′∈T之间的连边,当然边权不变。其原因在于,如果 u , v u,v u,v这条边在 M S T MST MST中,那么此时 S , T S,T S,T一定是联通的(假设不是联通的,那么跑 kruskal \text{kruskal} kruskal算法的流程就会出现矛盾)。因此,我们可以把一棵树 彻底等效成一条链

基于上述观察,我们不难得到将所有的二类边构成的森林等价转化成若干条链,然后用线段树维护答案的做法。

最后是一些 d p dp dp赋初值以及状态转移的细节,如果看题解的话问题可能不太大,不过自己做的时候可能要多尝试一下

复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn)。考场上能想到标算还是挺 n b nb nb的

问题来了,为什么一个 log ⁡ \log log的代码跑得这么慢呢?

#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define fi first
#define se second
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
const int N=3e5+5;
int n,m,Q,A[N],a[N],p[N],fa[N];
vector<int>w[N],v[N];
ll t[N<<2][2][2],val[N];
struct node{int x,y,z;bool operator <(const node&a)const{return z<a.z;}
}e[N];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);
}
void merge(int x,int y,int z){x=find(x),y=find(y);if(x!=y){if(v[x].size()<v[y].size())swap(x,y);fa[y]=x;for(auto X:v[y])v[x].pb(X);w[x].pb(z);for(auto X:w[y])w[x].pb(X);}
}
void pushup(int p,int val){for(int i=0;i<2;i++){for(int j=0;j<2;j++){t[p][i][j]=inf;for(int k=0;k<2;k++){for(int l=0;l<2;l++){if(k|l){t[p][i][j]=min(t[p][i][j],t[p<<1][i][k]+t[p<<1|1][l][j]+((k&l)?0:val));}}}}}
}
void init(int p,int l){for(int i=0;i<2;i++){for(int j=0;j<2;j++){t[p][i][j]=(i&j)?a[l]:0;}}
}
void build(int p,int l,int r){if(l==r){init(p,l);return;}int mid=l+r>>1;build(p<<1,l,mid),build(p<<1|1,mid+1,r);pushup(p,val[mid+1]);
}
void upd(int p,int l,int r,int x){if(l==r){init(p,l);return;}int mid=l+r>>1;x<=mid?upd(p<<1,l,mid,x):upd(p<<1|1,mid+1,r,x);pushup(p,val[mid+1]);
}
int main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);cin>>n>>m;for(int i=1;i<=n;i++)cin>>A[i];for(int i=1;i<=m;i++){int x,y,z;cin>>x>>y>>z,e[i]={x,y,z};}sort(e+1,e+1+m);for(int i=1;i<=n;i++)v[i].pb(i),fa[i]=i;for(int i=1;i<=m;i++){merge(e[i].x,e[i].y,e[i].z); }for(int i=1;i<n;i++){merge(i,i+1,inf);}int rt=0;for(int i=1;i<=n;i++)if(fa[i]==i)rt=i;assert(v[rt].size()==n);for(int i=0;i<v[rt].size();i++){p[v[rt][i]]=i+1;}assert(w[rt].size()==n-1);for(int i=0;i<w[rt].size();i++){val[i+2]=w[rt][i];}val[1]=inf;for(int i=1;i<=n;i++)a[p[i]]=A[i];build(1,1,n);cin>>Q;for(int i=1;i<=Q;i++){int x,y;cin>>x>>y,a[p[x]]=y;upd(1,1,n,p[x]);cout<<t[1][1][1]<<"\n";}
}

最后还是补一下 t 2 t2 t2。代码就算了,能过的代码为什么要优化呀

二进制的世界

用暴力来优化暴力

正解不如暴力

将 16 16 16位分为两部分:前 8 8 8位和后 8 8 8位。相信大家都猜到复杂度了吧,不过用乱搞优化位运算的确令人烦躁

设 f i , j f_{i,j} fi,j​表示前 8 8 8位为 i i i的数,与某个后 8 8 8为是 j j j的数进行位运算,后 8 8 8位结果的最大值以及方案数。

那么加入一个数 x x x的时候,设它的前 8 8 8位为 a a a,后八位为 b b b,只需要枚举 j j j,用 j o p t b j\ opt\ b j opt b更新所有 f a , j f_{a,j} fa,j​。查询 x x x的时候,用所有 ( i o p t a ) < < 8 ∣ f i , b (i\ opt\ a)<<8|f_{i,b} (i opt a)<<8∣fi,b​更新答案。

复杂度 O ( n m ) O(n\sqrt{m}) O(nm ​)。

代码出奇好写

#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define fi first
#define se second
using namespace std;
const int N=1e5+5;
int n,type,a[N],f[1<<8][1<<8],g[1<<8][1<<8];
string op;
int calc(int x,int y){if(op[0]=='x')return x^y;else if(op[0]=='o')return x|y;return x&y;
}
void ins(int x){int a=x>>8,b=x^(a<<8);for(int i=0;i<1<<8;i++){if(calc(b,i)>f[a][i]){f[a][i]=calc(b,i);g[a][i]=1;}else if(calc(b,i)==f[a][i]){g[a][i]++;}}
}
pair<int,int>solve(int x){int a=x>>8,b=x^(a<<8),res=0,res2=0;for(int i=0;i<1<<8;i++){if(g[i][b]&&((calc(a,i)<<8)|f[i][b])>res){res=((calc(a,i)<<8)|f[i][b]);}} for(int i=0;i<1<<8;i++){if(g[i][b]&&((calc(a,i)<<8)|f[i][b])==res){res2+=g[i][b];}}return {res,res2};
}
int main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);cin>>n>>op>>type;for(int i=1;i<=n;i++)cin>>a[i];ins(a[1]);for(int i=2;i<=n;i++){pair<int,int>res=solve(a[i]);if(!type){cout<<res.fi<<"\n";}else {cout<<res.fi<<" "<<res.se<<"\n";}ins(a[i]);}
}

【学习笔记】NOIP爆零赛8相关推荐

  1. 学习笔记(09):Python零基础轻松从入门到实战-字符和字符串-2

    立即学习:https://edu.csdn.net/course/play/26676/338775?utm_source=blogtoedu python零基础入门--字符和字符串-2 (1)字符 ...

  2. 学习笔记(17):零基础掌握 Python 入门到实战-重复利用,事半功倍

    立即学习:https://edu.csdn.net/course/play/26676/338764?utm_source=blogtoedu 位置参数 默认值放后面 def change_upper ...

  3. 学习笔记(14):零基础掌握 Python 入门到实战-重复利用,事半功倍

    立即学习:https://edu.csdn.net/course/play/26676/338764?utm_source=blogtoedu def add(x,y): r=x+y return r ...

  4. 学习笔记(1):零基础掌握 Python 入门到实战-用Python操作SQLite数据库

    立即学习:https://edu.csdn.net/course/play/26676/402880?utm_source=blogtoedu sqlite这一节用的软件是什么

  5. 学习笔记(2):零基础掌握 Python 入门到实战-一个圆点的何去何从(一)

    立即学习:https://edu.csdn.net/course/play/26676/338762?utm_source=blogtoedu 对象 :属性+方法 内置对象类型:整数.浮点数 字符串 ...

  6. Java学习笔记10(零压力理解继承多态权限修饰符)

    文章目录 继承 方法的重写(override) 四种访问权限修饰符: 关键字super 类对象的实例化的底层原理 多态 instanceof操作符 object类 继承 继承是Java最重要的,类之间 ...

  7. 学习笔记(3):零基础掌握 Python 入门到实战-一个圆点的何去何从(二)

    立即学习:https://edu.csdn.net/course/play/26676/338772?utm_source=blogtoedu python中可以进行四舍五入的内置函数:round(欲 ...

  8. 学习笔记 | Excel 2016 零基础教程

    教程地址:https://www.bilibili.com/video/BV1Xt411f7Hy?p=3&vd_source=220f6444db25e762a5c4790b58376364 ...

  9. 学习笔记----如何从零打造一个手游客户端

    1.技术选型.这个很重要.第一步错了,后面就是在错误的道路上渐行渐远. 如果要做2D游戏那就用cocos2d-x,如果要做3D那就用Unity.本来我是不想提这种一刀切的观点的,这样显得很没有水平,因 ...

最新文章

  1. 存储过程由结构表生成表
  2. 《你要么出众,要么出局》读书笔记
  3. 华为服务器系统激活id怎么更改,服务器id怎么设置
  4. 使用Poi读取xlsx类型的Excel
  5. C# 篇基础知识3——面向对象编程
  6. 在存储过程中如何使用另一个存储过程返回的结果集
  7. hosts文件中同一个域名两个IP的解析顺序
  8. IsPostBack须要注意的地方,这些都不是POSTBACK动作
  9. C语言判断某个字符串中 是否存在子字符串
  10. 【Ajax技术】解决XHR与中文乱码问题
  11. ffdshow 源代码分析 7: libavcodec视频解码器类(TvideoCodecLibavcodec)
  12. elisa数据处理过程图解_ELISA操作流程
  13. ws2812B+单片机驱动
  14. 2021年氧化工艺报名考试及氧化工艺模拟试题
  15. IT界最短的笑话:上中台!
  16. JUC学习笔记(二)——常用的辅助类
  17. 多文件自平衡云传输(四)资源发送端 —————— 开开开山怪
  18. 领英改版后无法搜索开发客户?解决方法来了,恢复后可以继续在领英搜索开发客户。
  19. MySQL 自增长主键 在删除数据后依然接着删除的数据增长
  20. java水仙花数(详解)

热门文章

  1. JDBC【数据库连接池、DbUtils框架、分页】
  2. android笔记 看过stormzhang大大的博客(关于像素,屏幕密度)
  3. 解决电脑无法进入休眠/睡眠状态,而仅关闭屏幕的问题
  4. 9*9的数独(dfs)
  5. 谈谈Linux中Redis的薪火相传与反客为主及如何实现
  6. 从视网膜到视皮层——视觉系统知多少
  7. JSP WAP 开发
  8. 细粒度 文档图像版面分析
  9. IDA使用手册_(1)
  10. [渝粤教育] 西南科技大学 财务管理与分析 在线考试复习资料(1)