【李超树】李超线段树维护凸包(凸壳) (例题:blue mary开公司+线段游戏+ZZH的旅行)

文章目录

  • 前言
  • 李超树
    • 引入(斜率优化)
    • 什么是李超树?
    • 李超树活着能干点什么?
  • 算法思想(使用手册?)
    • 插入
    • 查询
  • 模板
    • 判断是否覆盖(优不优)
    • 插入
    • 查询
  • 例题
    • 板题:BlueMary开公司
      • 分析
      • code
    • 线段游戏
      • 分析
      • code
  • 拓展——(动态开点李超树维护凸包)
    • ZZH的旅行
      • solution
      • code

前言

最近两场xie教练的考试都拉到了动态维护多条直线求最值的凸包问题
然后很愉快的一道都做不出来呢
所以学习了一下下,就写了个小博客

李超树

引入(斜率优化)

学习了c++c++c++,就必少不了dpdpdp的花式玩法
也就不会错过各种O(1),O(log)O(1),O(log)O(1),O(log)的优化
前缀和…斜率优化…单调队列…单调栈…


我们看一个dpdpdp状态转移方程式
dp[i]=max{dp[j]+bi∗aj+a[i]},j<idp[i]=max\{dp[j]+b_i*a_j+a[i]\},j<idp[i]=max{dp[j]+biaj+a[i]},j<i

一般这种长相,噢不,准确来说,很多dpdpdp的这种长相,都会跟凸包挂钩
在这里插入图片描述
因为出题人不想考那么板的dp送分,就只能搞搞单调让你优化
而我们目前已知的解决凸包就是斜率优化


假设题目保证aia_iai递增

假设j<k<ij<k<ij<k<i且决策点jjj优于决策点kkk,则有
dp[j]+bi∗aj+a[i]>dp[k]+bi∗ak+b[i]①dp[j]+b_i*a_j+a[i]>dp[k]+b_i*a_k+b[i]\ \ \ \ \ \ \ ①dp[j]+biaj+a[i]>dp[k]+biak+b[i]       dp[j]−dp[k]>bi∗(ak−aj)②dp[j]-dp[k]>b_i*(a_k-a_j)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ②dp[j]dp[k]>bi(akaj)                                题目保证aaa单增,即ak−aj>0a_k-a_j>0akaj>0,继续变形得到
dp[j]−dp[k]ak−aj>bi③\frac{dp[j]-dp[k]}{a_k-a_j}>b_i\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ③akajdp[j]dp[k]>bi                                                   
上述过程其实就是斜率优化的推导过程,这种情况下我们仍然可以吃老本——走斜率优化


但是,如果题目不保证aia_iai单调呢??这个时候,斜率优化可以慢走不送了

这个条件去掉后,为什么斜率优化不行了呢??
再回到上面的推导过程,②能推导出③,实际上是把ak−aja_k-a_jakaj除了过去
也就是说我们是肯定了ak−aja_k-a_jakaj的符号才敢这样转移
一旦不确定了,大于小于符号就会错乱,无法斜率优化
ps:我刚刚偷换了一下,我把单增变成了题目不保证单调,因为单减也是可以斜率优化的
在这里插入图片描述

所以斜率优化是建立在单调的基础上的


此时我们怎么办呢??

  1. 暴力的气息扑面而来
  2. 祈祷数据会有单调的(概率:0.00…01%) 除非你是出数据的
  3. 乱搞
  4. 其它优秀的做法
  5. 我们的主角当当当————李超树!!!!yyds!

在这里插入图片描述

什么是李超树?

李超树 额(⊙﹏⊙)…按xie教练的话就是——懒标记永久化的线段树

明明就是个懒标记永久化,搞不懂为什么要专门取个名字叫李超树 ·····················——xie教练

管他的,反正我们不需要了解,它能有点用才是我们关注的!

李超树活着能干点什么?

  1. 维护一段区间的多条直线
  2. 支持单点查询多条直线的极值,如查询xxx处的多条直线的纵坐标最大值
  3. 支持区间查询直线极值,如查询区间[l,r][l,r][l,r]中各直线最值的最大值

本篇博客仅从“单点查询多条直线的极值”入手,因为博主目前只会这一种
在这里插入图片描述

只要你能写出 f[i]=max/min(f[j]∗h(i)+g[j])+t(i)f[i]=max/min(f[j]*h(i)+g[j])+t(i)f[i]=max/min(f[j]h(i)+g[j])+t(i)
搞那么复杂干什么, 其实就是你能写出一条一次函数的解析式 y=kx+by=kx+by=kx+b
李超树就能硬刚!
在这里插入图片描述

算法思想(使用手册?)

维护上凸包和下凸包差不多,我们以维护最大值为例

李超树每个区间记录的是该区间中点midmidmid处的最大/小函数值对应的函数

插入

分两种情况

  1. 完全覆盖
    在这里插入图片描述
    新的红线在[l,r][l,r][l,r]区间上完全优于原来该区间存的直线,那么将直接进行全覆盖
    然后就returnreturnreturn,不用去更新左右子树
    至于为什么?跟查询写法有关,也跟部分覆盖挂钩
    因为此时更新后如果没有出现部分覆盖的情况,查询我们也会查到这条直线的值
    如果出现了部分覆盖的情况,此时的红线就会部分下放更新
    反正此时的黄线已经是个废物了,只需要知道这点就o了
  2. 部分覆盖
    2-1.
    在这里插入图片描述
    首先这个区间[l,r][l,r][l,r]存的直线与midmidmid挂钩,此时红线在midmidmid处的函数值优于黄线
    所以李超线段树[l,r][l,r][l,r]这一个区间就会存红线的解析式
    那这个黄线呢??它也并不是全无用,我们需要继续递归右子树,去更新蓝色部分的区间
    在这里插入图片描述
    2-2.
    在这里插入图片描述
    此时红线在midmidmid处的函数值劣于黄线,李超线段树[l,r][l,r][l,r]这一个区间的解析式仍然是黄线
    但这个红线呢??也并不是全无用,我们需要继续递归做子树,去更新蓝色部分的区间
    在这里插入图片描述

这三种情况怎么判断呢?就是怎么写呢?
很简单——直线是单调的
我们只需要掌握l,mid,rl,mid,rl,mid,r三个点的两点函数值就可以了,具体可看模板
在这里插入图片描述

查询

每一个区间都存了一条直线,可能相同也可能不同
一个点被多个区间包含,也就会被多条直线包含
所以我们一路上下来遇到的每一个区间都要算一次xxx对应的函数值,取最大值
有可能先遇到的直线的函数值比后遇到的直线的函数值还小,这是有可能的
因为那些区间的函数解析式是根据那些区间的中点midimid_imidi的函数值决定的
谁管你这个小虾皮
举个栗子
在这里插入图片描述
这一路上涉及到的四个点的每一条解析式(黑线)都要把xxx带进去算出y1,y2,y3,y4y_1,y_2,y_3,y_4y1,y2,y3,y4

模板

判断是否覆盖(优不优)

double calc( node num, int x ) {return num.k * x + num.b;
}bool cover( node old, node New, int x ) {return calc( old, x ) <= calc( New, x ); 
}

插入

void insert( int num, int l, int r, node New ) {if( cover( t[num], New, l ) && cover( t[num], New, r ) ) {//新的直线完全覆盖了原区间的最优直线 t[num] = New;return;}if( l == r ) return;int mid = ( l + r ) >> 1;if( cover( t[num], New, mid ) )//区间[l,r]维护x=mid的最优值 swap( t[num], New );//现在这条直线需要继续往下去更新左右儿子(如果这条直线更优) if( cover( t[num], New, l ) ) insert( num << 1, l, mid, New );if( cover( t[num], New, r ) )insert( num << 1 | 1, mid + 1, r, New );
}

查询

这个版本有限制!!!
这个版本有限制!!!
这个版本有限制!!!
在这里插入图片描述

也许是我写法问题
此版本查询维护的是直线,也就是说每一条直线都会覆盖到所有的查询点
我们知道[l,r][l,r][l,r]区间维护的函数解析式是当x=midx=midx=mid时,函数值最大的那条解析式
因为每一条线都能覆盖完,所以每一个区间[l,r][l,r][l,r]都会维护一条直线
于是乎此版本的优化:x=midx=midx=mid时直接返回,不再寻找左右儿子
在这个前提下,这个优化才有正确性保障

double query( int num, int l, int r, int x ) {double ans = -1e9;int mid = ( l + r ) >> 1;if( x < mid ) ans = query( num << 1, l, mid, x );if( mid < x ) ans = query( num << 1 | 1, mid + 1, r, x );return max( ans, calc( t[num], x ) );
}

这一个版本维护的是线段,可能只会覆盖到一部分查询点

对应的插入操作也会发生改变,[l,r][l,r][l,r]能插入当且仅当[l,r][l,r][l,r]被某条直线完全包含,我们要再写一个modifymodifymodify

void modify( int num, int l, int r, int L, int R, node New ) {if( L > R ) return;if( L <= l && r <= R ) {insert( num, l, r, New );return;}int mid = ( l + r ) >> 1;if( R <= mid ) modify( num << 1, l, mid, L, R, New );else if( mid < L ) modify( num << 1 | 1, mid + 1, r, L, R, New );else {modify( num << 1, l, mid, L, mid, New );modify( num << 1 | 1, mid + 1, r, mid + 1, R, New );}
}

也就是说[l,r][l,r][l,r]区间如果没有被一条直线完全覆盖的话,这个区间是没有存直线的
那么当我们继续沿用之前的优化,x=midx=midx=mid就返回,很可能这段区间压根没有直线解析式
所以我们必须继续询问左儿子或者右儿子

打破砂锅问到底

double query( int num, int l, int r, int x ) {double ans;if( l == r ) return calc( t[num], x - 1 );int mid = ( l + r ) >> 1;if( x <= mid ) ans = query( num << 1, l, mid, x );else ans = query( num << 1 | 1, mid + 1, r, x );return max( ans, calc( t[num], x - 1 ) );
} 

直线也可看作一条无限长的线段,因此此版本适用范围广
在这里插入图片描述
如果不是很理解,下面两道例题就能很好的辨析出来,┏ (゜ω゜)=☞
线段游戏的样例就会发现查询的写法不同会有问题,可以分布调试看看

例题

板题:BlueMary开公司

分析

每一个项目看作一条直线,而某一天就是查询点
依题意可得,每一个项目可以覆盖每一天,也就是直线覆盖所有点情况
两种查询模板都可以直接上

code

#include <cstdio>
#include <iostream>
using namespace std;
#define maxn 50005
struct node {double k, b;node(){}node( double K, double B ) {k = K, b = B;}
}t[maxn << 2];
int n;double calc( node num, int x ) {return num.k * x + num.b;
}bool cover( node old, node New, int x ) {return calc( old, x - 1 ) <= calc( New, x - 1 ); //题目原因 符合要求的x实际上是需要-1才算得出正确收益 
}void insert( int num, int l, int r, node New ) {if( cover( t[num], New, l ) && cover( t[num], New, r ) ) {t[num] = New;return;}if( l == r ) return;int mid = ( l + r ) >> 1;if( cover( t[num], New, mid ) )swap( t[num], New );if( cover( t[num], New, l ) ) insert( num << 1, l, mid, New );if( cover( t[num], New, r ) )insert( num << 1 | 1, mid + 1, r, New );
}double query( int num, int l, int r, int x ) {double ans = -1e9;int mid = ( l + r ) >> 1;if( x < mid ) ans = query( num << 1, l, mid, x );if( mid < x ) ans = query( num << 1 | 1, mid + 1, r, x );return max( ans, calc( t[num], x - 1 ) );
} 
/*
已测试,此写法依然可过
double query( int num, int l, int r, int x ) {double ans;if( l == r ) return calc( t[num], x - 1 );int mid = ( l + r ) >> 1;if( x <= mid ) ans = query( num << 1, l, mid, x );else ans = query( num << 1 | 1, mid + 1, r, x );return max( ans, calc( t[num], x - 1 ) );
} 
*/
int main() {scanf( "%d", &n );while( n -- ) {char opt[10]; int k, b, t;scanf( "%s", opt );if( opt[0] == 'Q' ) {scanf( "%d", &t );printf( "%d\n", int( query( 1, 1, maxn, t ) / 100 ) );}else {double k, b;scanf( "%lf %lf", &b, &k );insert( 1, 1, maxn, node( k, b ) );}}	return 0;
} 

线段游戏

分析

这道题就很特别了,我们维护的不再是一条直线,而是一条线段
这条线段只能覆盖有限的查询点,而不能覆盖的点我们是不能进行求解的

code

#include <cstdio>
#include <iostream>
using namespace std;
#define maxn 100000
#define inf 0x7f7f7f7f
struct node {double k, b;node(){}node( double K, double B ) {k = K, b = B;}
}t[( maxn + 5 ) << 2];
int n, m;double calc( node num, int x ) {return num.k * x + num.b;
}bool cover( node old, node New, int x ) {return calc( old, x ) < calc( New, x );
}void insert( int num, int l, int r, node New ) {if( cover( t[num], New, l ) && cover( t[num], New, r ) ) {t[num] = New;return;}if( l == r ) return;int mid = ( l + r ) >> 1;if( cover( t[num], New, mid ) )swap( t[num], New );if( cover( t[num], New, l ) )insert( num << 1, l, mid, New );if( cover( t[num], New, r ) )insert( num << 1 | 1, mid + 1, r, New );
}void modify( int num, int l, int r, int L, int R, node New ) {if( L > R ) return;if( l == L && R == r ) {insert( num, l, r, New );return;}int mid = ( l + r ) >> 1;if( R <= mid ) modify( num << 1, l, mid, L, R, New );else if( mid < L ) modify( num << 1 | 1, mid + 1, r, L, R, New );else {modify( num << 1, l, mid, L, mid, New );modify( num << 1 | 1, mid + 1, r, mid + 1, R, New );}
}double query( int num, int l, int r, int x ) {if( l == r ) return calc( t[num], x );double ans;int mid = ( l + r ) >> 1;if( x <= mid ) ans = query( num << 1, l, mid, x );else ans = query( num << 1 | 1, mid + 1, r, x );return max( ans, calc( t[num], x ) );
/*
这种写法是不对的,原因上面已经分析过了......double ans = -inf;int mid = ( l + r ) >> 1;if( x < mid ) ans = query( num << 1, l, mid, x );if( mid < x ) ans = query( num << 1 | 1, mid + 1, r, x );return max( ans, calc( t[num], x ) );
*/
}void build( int num, int l, int r ) {t[num].k = 0, t[num].b = -inf;if( l == r ) return;int mid = ( l + r ) >> 1;build( num << 1, l, mid ), build( num << 1 | 1, mid + 1, r );
}int main() {scanf( "%d %d", &n, &m );build( 1, 1, maxn );int x0, x1, y1, x2, y2, opt;double k, b;for( int i = 1, x1, y1, x2, y2;i <= n;i ++ ) {scanf( "%d %d %d %d", &x1, &y1, &x2, &y2 );if( x1 == x2 ) k = 0, b = max( y2, y1 );else k = ( y2 - y1 ) * 1.0 / ( x2 - x1 ), b = y1 - k * x1;modify( 1, 1, maxn, max( 1, min( x1, x2 ) ), min( maxn, max( x1, x2 ) ), node( k, b ) );}while( m -- ) {scanf( "%d", &opt );if( opt ) {scanf( "%d", &x0 );double ans = query( 1, 1, maxn, x0 );printf( "%.6f\n", ( ans <= -inf ? 0 : ans ) );}else {scanf( "%d %d %d %d", &x1, &y1, &x2, &y2 );if( x1 == x2 ) k = 0, b = max( y2, y1 );else k = ( y2 - y1 ) * 1.0 / ( x2 - x1 ), b = y1 - k * x1;modify( 1, 1, maxn, max( 1, min( x1, x2 ) ), min( maxn, max( x1, x2 ) ), node( k, b ) );}}return 0;
} 

拓展——(动态开点李超树维护凸包)

ZZH的旅行

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

solution

在这里插入图片描述

code

有一坨不像我🐎风的快读快输代码,是因为我TTT了,真的⛏不动了,加了就能AAA
在这里插入图片描述

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define int long long
#define maxn 1000005
vector < pair < int, int > > G[maxn];
int n;
int aa[maxn], bb[maxn], dep[maxn];
int X[maxn], K[maxn], B[maxn], rt[maxn], dp[maxn];
int son[maxn][2];namespace IO{const int sz=1<<22;char a[sz+5],b[sz+5],*p1=a,*p2=a,*t=b,p[105];inline char gc(){return p1==p2?(p2=(p1=a)+fread(a,1,sz,stdin),p1==p2?EOF:*p1++):*p1++;}template<class T> void read(T& x){x=0; char c=gc();for(;c<'0'||c>'9';c=gc());for(;c>='0'&&c<='9';c=gc())x=x*10+(c-'0');}inline void flush(){fwrite(b,1,t-b,stdout),t=b; }inline void pc(char x){*t++=x; if(t-b==sz) flush(); }template<class T> void print(T x,char c='\n'){if(x==0) pc('0'); int t=0;for(;x;x/=10) p[++t]=x%10+'0';for(;t;--t) pc(p[t]); pc(c);}struct F{~F(){flush();}}f; 
}
using IO::read;
using IO::print;int insert( int x, int l, int r, int k, int b, int id ) {if( ! x ) {son[id][0] = son[id][1] = 0;K[id] = k, B[id] = b;return id;}int mid = ( l + r ) >> 1;if( X[mid] * K[x] + B[x] < X[mid] * k + b )swap( K[x], k ), swap( B[x], b );if( l < r ) {if( k >= K[x] ) son[x][1] = insert( son[x][1], mid + 1, r, k, b, id );else son[x][0] = insert( son[x][0], l, mid, k, b, id );}return x;
}int query( int x, int l, int r, int id ) {if( ! x ) return -1e18;int ans = K[x] * X[id] + B[x];int mid = ( l + r ) >> 1;if( id <= mid ) ans = max( ans, query( son[x][0], l, mid, id ) );else ans = max( ans, query( son[x][1], mid + 1, r, id ) );return ans;
}int merge( int x, int y, int l, int r ) {if( ! x || ! y ) return x + y;int mid = ( l + r ) >> 1;son[x][0] = merge( son[x][0], son[y][0], l, mid );son[x][1] = merge( son[x][1], son[y][1], mid + 1, r );if( K[x] * X[mid] + B[x] < K[y] * X[mid] + B[y] )	swap( K[x], K[y] ), swap( B[x], B[y] );if( l < r ) insert( x, l, r, K[y], B[y], y );return x;
}void dfs1( int u, int fa ) {for( int i = 0;i < G[u].size();i ++ ) {int v = G[u][i].first, w = G[u][i].second;if( v == fa ) continue;else dep[v] = dep[u] + w, dfs1( v, u );}
}void dfs2( int u, int fa ) {for( int i = 0;i < G[u].size();i ++ ) {int v = G[u][i].first;if( v == fa ) continue;else dfs2( v, u ), rt[u] = merge( rt[u], rt[v], 1, n );}dp[u] = max( 0ll, query( rt[u], 1, n, lower_bound( X + 1, X + n + 1, aa[u] + dep[u] ) - X ) );rt[u] = insert( rt[u], 1, n, bb[u], dp[u] - bb[u] * dep[u], u );
}signed main() {read( n );for( int i = 1;i <= n;i ++ )read( aa[i] ), read( bb[i] );for( int i = 1, u, v, d;i < n;i ++ ) {read( u ), read( v ), read( d );G[u].push_back( make_pair( v, d ) );G[v].push_back( make_pair( u, d ) );}dfs1( 1, 0 );for( int i = 1;i <= n;i ++ )X[i] = aa[i] + dep[i];sort( X + 1, X + n + 1 );dfs2( 1, 0 );for( int i = 1;i <= n;i ++ )print( dp[i] );return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317776.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

老牌开源Office操作组件NPOI现已支持.NET Core

昨天在微信群里听到老牌Excel开发利器NPOI的作者瞿总说4.6.1版本的NPOI已经支持.NET Standard 2.0了&#xff0c;这也就意味着你可以在.NET Core中使用NPOI了。作者&#xff1a;依乐祝原文地址 &#xff1a;https://www.cnblogs.com/yilezhu/p/10269281.html写在前面曾经的.NET…

.NET西安社区 [拥抱开源,又见 .NET] 第二次活动简报

「拥抱开源, 又见 .NET」随着 .NET Core的发布和开源&#xff0c;.NET又重新回到人们的视野。 .NET Core的下个3.0即将release&#xff0c;加入非常多的新功能&#xff0c;越来越拥抱变化&#xff0c;DevOps和Microservice的最佳实践已经在 .NET Core落地&#xff0c;比如 Ocel…

[dsu on tree]树上启发式合并总结(算法思想及模板附例题练习)

文章目录前言树上启发式合并引入算法思想时间复杂度模板练习例题&#xff1a;CF600E Lomsat gelralsolutioncodeCF208E Blood CousinssolutioncodeCF570D Tree RequestssolutioncodeCF1009F Dominant Indicessolutioncode前言 最近不是在⛏李超树嘛&#xff0c;然后就去玩了下…

领域驱动设计,让程序员心中有码(七)

领域驱动设计- 让程序员心中有码&#xff08;七&#xff09;-设计原则和设计模式&#xff0c;互联网开发者们共同的追求前言多年来&#xff0c;笔者一直从事传统软件企业的软件开发和项目管理工作。笔者发现在众多的传统软件企业中&#xff0c;评判优秀开发者的标准往往是技能的…

cf1504. Travelling Salesman Problem

cf1504. Travelling Salesman Problem 题意&#xff1a; n个城市&#xff0c;编号1~n&#xff0c;每个城市有美丽值a[i]&#xff0c;现在要从城市1出发&#xff0c;其他所有城市走一遍&#xff0c;最后回到城市1&#xff0c;城市i到j的花费为max(ci,aj-ai)&#xff0c;ci为第…

[NOIP-S 2020]游记(附考前注意事项)

呜呼起飞T1&#xff1a;排水系统T2&#xff1a;字符串匹配T3&#xff1a;移球游戏T4&#xff1a;微信步数总述考前注意事项T1&#xff1a;排水系统 嗯—— 怎么说呢&#xff1f;&#xff1f; 比赛开始后迅速通读三遍题 顶着第一题肯定是打卡题的心态 哪怕是恶心模拟也得上&…

程序猿修仙之路--数据结构之你是否真的懂数组?

数据结构但凡IT江湖侠士&#xff0c;算法与数据结构为必修之课。早有前辈已经明确指出&#xff1a;程序算法数据结构 。要想在之后的江湖历练中通关&#xff0c;数据结构必不可少。数据结构与算法相辅相成&#xff0c;亦是阴阳互补之法。开篇说道数组&#xff0c;几乎每个IT江…

Rolling The Polygon Gym - 102222B

Rolling The Polygon Gym - 102222B 题意&#xff1a; 给你一个多边形&#xff0c;给你内部一个点Q&#xff0c;多边形在平面上滚动一周&#xff08;当有一个边第二次触地滚动停止&#xff09;&#xff0c;问Q的轨迹长度 题解&#xff1a; 计算几何题目 自己一直不是很擅长…

Asp.Net Core 轻松学-经常使用异步的你,可能需要看看这个文章

前言事情的起因是由于一段简单的数据库连接代码引起&#xff0c;这段代码从语法上看&#xff0c;是没有任何问题&#xff1b;但是就是莫名其妙的报错了&#xff0c;这段代码极其简单&#xff0c;就是打开数据库连接&#xff0c;读取一条记录&#xff0c;然后立即更新到数据库中…

try.dot.net 的正确使用姿势

来源&#xff1a;https://www.cnblogs.com/7tiny/p/10277600.html【简介】微软官方前不久发布了 try.dot.net 这个有趣的网址&#xff0c;开始只是图个新鲜看了一下&#xff0c;后面通过自身实践过后&#xff0c;发现这着实算是个“有趣”的站点&#xff01;首先我们大概地列举…

A - TOYS POJ - 2318

A - TOYS POJ - 2318 题意&#xff1a; 一个盒子中有n个隔板&#xff0c;分出n1个空间&#xff08;从左往右空间的编号分别是0…n&#xff09;&#xff0c;&#xff08;隔板之间不会相交&#xff0c;且按照从左往右的顺序给出&#xff09;&#xff0c;现在给你m个坐标的物品&…

[BJOI2017]魔法咒语(AC自动机+DP+矩阵快速幂)

文章目录titlesolutioncodetitle solution 针对数据编程才是坠吊的&#xff01;&#xff01;&#xff01; 观察数据&#xff0c;发现分隔数据的LLL跨度过大&#xff0c;没有衔接——推测很有可能是分数据做法 ①&#xff1a;考虑L≤100L\le100L≤100的情况 可以暴力DPDPDP转移…

[国家集训队]middle(二分+主席树[中位数思维题])

文章目录点击查看solutioncode点击查看 solution 简单口胡一下就跑 考虑二分答案ansansans 区间[x1,x2],x1∈[a,b]&#xff0c;x2∈[c,d][x1,x2],x1∈[a,b]&#xff0c;x2∈[c,d][x1,x2],x1∈[a,b]&#xff0c;x2∈[c,d] 大于等于ansansans的设为111&#xff0c;小于ansans…

使用Roslyn脚本化C#代码,C#动态脚本实现方案

来源&#xff1a;https://www.cnblogs.com/7tiny/p/10279349.html【前言】Roslyn 是微软公司开源的 .NET 编译器。编译器支持 C# 和 Visual Basic 代码编译&#xff0c;并提供丰富的代码分析 API。Roslyn不仅仅可以直接编译输出&#xff0c;难能可贵的就是上述描述中的开放了编…

[构造训练]CF1227G Not Same,CF1375H Set Merging,CF1364E X-OR

文章目录T1&#xff1a;CF1227G Not SamesolutioncodeT2&#xff1a;CF1364E X-ORsolutioncodeT3&#xff1a;CF1375H Set Mergingsolutioncode~~脑子是个好东西&#xff0c;希望人人都有构造真的不是个东西&#xff0c;看了一天视频&#xff0c;没有一道题会做~~ T1&#xff…

asp.net core 环境(Development、Staging 、Production)

一.在asp.net core中使用多个环境ASP.NET Core 配置是基于运行时环境, 使用环境变量。ASP.NET Core 在应用启动时读取环境变量ASPNETCORE_ENVIRONMENT&#xff0c;并将该值存储在 IHostingEnvironment.EnvironmentName 中。ASPNETCORE_ENVIRONMENT 可设置为任意值&#xff0c;但…

ASP.NET Core 2.1 : 图解路由(2.1 or earler)

本文通过一张图来看一下路由的配置以及请求处理的机制。 一、概述路由主要有两个主要功能&#xff1a;将请求的URL与已定义的路由进行匹配&#xff0c;找到该URL对应的处理程序并传入该请求进行处理。根据已定义的路由生成URL这两个功能看起来这两个是相反的。A.路由的配置路由…

[数据结构专训][GXOI/GZOI2019]旧词,[hdu5118]GRE Words Once More!,[hdu6333]Problem B. Harvest of Apples

文章目录T1&#xff1a;[GXOI/GZOI2019]旧词solutioncodeT2&#xff1a;GRE Words Once More!solutioncodeT3&#xff1a;Problem B. Harvest of ApplessolutioncodeT1&#xff1a;[GXOI/GZOI2019]旧词 点击查看 solution 考虑k1k1k1的情况 由于dep[lca(x,y)]∣{z,zdep[lca(…

浅谈c#垃圾回收机制(GC)

写了一个window服务&#xff0c;循环更新sqlite记录&#xff0c;内存一点点稳步增长。三天后&#xff0c;内存溢出。于是&#xff0c;我从自己的代码入手&#xff0c;查找到底哪儿占用内存释放不掉&#xff0c;最终明确是调用servicestack.ormlite更新sqlite数据库造成的。至于…

洛谷P2497:基站建设(splay、斜率优化)

所谓splay斜率优化dp&#xff0c;就是利用splay和斜率对dp进行优化 &#xff08;逃&#xff09; 解析 在斜优的时候&#xff0c;有时我们会发现我们插入的点的横坐标并不单调 这个时候我们就无法利用单调队列维护凸包了 这时&#xff0c;我们就要请出今天的主角&#xff1a;s…