我的题解(17年)

我的题解
2017.9

又重新开始学DSAA了,偶然翻到自己17年写的题解,五年过去了,现在的DSAA课还没当年做的题难,以此来对以往的oi生涯留个纪念吧

1.洛谷1531
线段树模板:区间最值
2.洛谷 2068
线段树模板:单点更新,区间求和
3.codevs 4919
线段树:区间更新,区间查询(余数)
给你N个数,有两种操作
1:给区间[a,b]内的所有数都增加X
2:询问区间[a,b]能被7整除的个数
第一问直接上模板,第二问用一个数组x[]来记录除7余数的个数:如x[1]表示区间内除7余1 的数的个数,在进行区间更新如加5的时候将x的每一位向后移5 位
X[0]  x[5]
X[1]  x[6]
X[2]  x[0]
X[3]  x[1]
X[4]  x[2]
X[5]  x[3]
X[6]  x[4]
Change 即为更改X[]的操作

void change(int u,int c)
{
int tx[10];
for(int i = 0; i < p; ++i) tx[i] = t[u].x[i];
for(int i = 0; i < p; ++i) t[u].x[i] = tx[(i - c + p) % p];
t[u].sum = t[u].x[0];
}
4.codevs 1082
线段树:区间更新,区间求和
重点在于lazy的使用
与单点查询不同的是在更新和查询时都需要pushdown(下放lazy)
5.vj a hdu1166
树状数组:单点更新,区间求和(区间查询)
lowbit(k)就是把k的二进制的高位1全部清空,只留下最低位的1和后面的0
t = lowbot(k) 就是求出t = 2的x次方 ,并且 t <= k;
如:lowbit(5) = 4; lowbit(7) = 4;lowbit(2) = 2;
Lowbit(k) = k &(-k);具体原理涉及补码.
对于一个数,我们有原码,反码,补码三种表现形式
1、 原码:原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值.
a) [+1]原 = 0000 0001
b) [-1]原 = 1000 0001
2、反码:正数的反码是其原码,负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
c) [+1] = [00000001]原 = [00000001]反
d) [-1] = [10000001]原 = [11111110]反
3、补码:正数的补码就是其原码也是其反码,负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
e) [+1] = [00000001]原 = [00000001]反 = [00000001]补
f) [-1] = [10000001]原 = [11111110]反 = [11111111]补
在计算机中,减去一个正数,被看做是加上一个负数,就可以只计算加法,那么使用补码可以使得计算过程简单,并且符号位也直接参与运算,就不用特判符号位。
计算十进制的表达式: 1-1=0
= 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=[0000 0000]原

lowbit(k)就是把k的二进制的高位1全部清空,只留下最低位的1和后面的0,
比如10的二进制是1010,则lowbit(k) = lowbit(1010)
= 0010(2进制) = 2(十进制),实现方法:lowbit(k)=k&-k。
有了lowbit(k),我们就可以方便的将a和c数组联系在一起了,c[k]表示从a[k]开始往前连续lowbit(k)个数的和
比如c[6] = 从a[6]开始往前连续lowbit(6)个数的和 = c[6] + c[4]
5.洛谷1119图论
B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响。但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车。换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄。给出B地区的村庄数N,村庄编号从0到N-1,和所有M条公路的长度,公路是双向的。并给出第i个村庄重建完成的时间t[i],你可以认为是同时开始重建并在第t[i]天重建完成,并且在当天即可通车。若t[i]为0则说明地震未对此地区造成损坏,一开始就可以通车。之后有Q个询问(x, y, t),对于每个询问你要回答在第t天,从村庄x到村庄y的最短路径长度为多少。如果无法找到从x村庄到y村庄的路径,经过若干个已重建完成的村庄,或者村庄x或村庄y在第t天仍未重建完成 ,则需要返回-1。
这道题与常见的灾后重建有类似又有不同:常见的灾后重建是村庄完好重建道路,往往是跑最短路或最小生成树的模板,但此题是村庄受损道路完好,想到与点关系密切的最短路算法就只有floyd.再看这道题的N只有200,更加肯定了是floyd。
思路是对于每个询问,去依次枚举这个询问前恢复了的每个点。
这题和Floyd模板不同的是用了2个数组,g[][]和dis[][]来跑floyd,因为对于每个询问,恢复的点都不同,dis[a][b]表示当前这个询问时a到b的最短路程,而g[a][b]表示若所有点都可用时a到b的最短路程。

6.poj 1724
题目大意:N个城市,编号1到N。城市间有R条单向道路。
每条道路连接两个城市,有长度和过路费两个属性。
Bob只有K块钱,他想从城市1走到城市N。求在钱够花的情况下的最短路。如果到不了N,输出-1
思路:dijkstra以长度排序,每次松弛的时候判断钱用完没有,如果没有:松弛;如果用完了则吧进行松弛。

7.poj 1062
题目大意:有N个物品,每个物品都有自己的价格,但同时某些物品也可以由其他的(可能不止一个)替代品,这些替代品的价格比较“优惠”,问怎么样选取可以让你的花费最少来购买到物品1。
很多人用图论最短路做,但我认为这是典型的dfs
思路:对于每一件物品,如果已经被搜过,就直接返回,否则,我们就去搜索TA的替代品。

8.hdu 1556 差分
题目大意:
N个气球排成一排,从左到右依次编号为1,2,3…N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色。但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗?
差分思想
怎样预处理出sum[i],我们新增数组s,
一开始s状态为 0 0 0 0 0 0 0,则sum为0 0 0 0 0 0 0,
遇到一个操作为3 – 5涂色,则将s[3] + 2,s[6] - 2,
S[]变为0 0 2 0 0 -2 0,sum[]变为0 0 2 2 2 0 0最后输出sum[]即可

9.codevs 2488 && codevs 2833 && 洛谷1137 拓扑排序模板
1.让所有入度为0的点入队;
2.从队列中取出一个点,使所有与之相连的点入度减一。
重复1,2 直到队列为空。若此时所有点均入队,则图上没环,否则有环。

10.rqnoj 86 && rqnoj 341 图论:最短路模板
Spfa vs dijkstra
Spfa:vis[]判断的是该点有无入队。
void spfa()
{
q.push(1);dis[1] = 0;vis[1] = 1;
while(!q.empty())
{
int u = q.front();q.pop();vis[u] = 0;
for(int i = head[u]; i != -1; i = e[i].next)
{
int v = e[i].v;
if(dis[v] > dis[u] + e[i].w)
{
dis[v] = dis[u] + e[i].w;
if(!vis[v])
{
vis[v] = 1;
q.push(v);
}
}
}
}
}
Dijkstra:vis[]判断的是该点有无被松弛过。
void dijkstra()
{
dis[1] = 0;
q.push(make_pair(dis[1],1));
while(!q.empty())
{
int u = q.top().second;
q.pop();
if(vis[u]) continue;
vis[u] = 1;
for(int i = head[u]; i != -1; i = e[i].next)
{
int v = e[i].v;
if(dis[v] > dis[u] + e[i].w)
{
dis[v] = dis[u] + e[i].w;
q.push(make_pair(dis[v],v));
}
}
}
}
11.codevs 1021
题目大意:有N个城市,M条道路,每条道路需T分钟通过,其中有一条道路正在维修,无法通车,但不知道是哪一条,求从1号城市到n号城市的最长时间。
思路:先跑一遍最长路(记录下每条边:可通过fa[]),在依次删去最长路上的边,再跑最长路。
注意:删边的时候要同时删正向边和反向边;每次跑最长路时需将dis[]置0
11.codevs 2059逃出克隆岛
题目大意:N行M列的矩阵,’Y’表示yh的出生位置,C表示克隆岛的出口,’#’表示该处不可通过,’*’表示通过该处需要消耗金币cost, ’P’表示传送阵,任意两个传送阵之间可以免费互相传送。求从’Y’出发到’C’最少需要消耗多少金币
分析:此题关键在于任意两个传送门可以互相免费传送,有因为求最少消耗的金币,所以用bfs
只需先预处理出t[a][b]表示a到b有传送门,即可。

12.codevs 1041 Car的旅行路线
题不难,关键在于数据处理,直接上代码吧。

13.poj 2299 线段树 || 树状数组求逆序对
思路:建一个最大值为这些数中的最大值的线段树或树状数组,每读入一个数a[i],就更新线段树,再查找比a[i]小的数有多少个,如:k个,则i – k 就是第i个数的逆序数的个数,累加起来就是总的逆序对数。
变式:hdu 1394 本题就是求循环移位后逆序数的最小值。注意推导。

14.codevs 1183 泥泞的道路
题目大意:有N个城市,任意两城市间有道路连接,求从1号城市到N号城市总路程/总时间最大的路线
思路:二分答案,将总路程/总时间的比值进行二分,设为ans。以 w = s – t * ans;建边,跑最短路。如果有正环就继续,没有正环,就停止。注意推导。
(s1+s2+s3+……+sn)/(t1+t2+t3……+tn)
显然对于图的权值和是单调的,显然其中的路径也是单调的(ans加大,w下降)而且合法的ans要使路径权值和为0,我们目标是求一最大的ans那么路径的权值也应更大才能使之为0,即每次求单源最长路;

15.codevs 1017
题目大意:设有一个长度为N的数字串,要求选手使用K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大。
dp[i][j]表示从1 -> i 用了j个乘号
dp[i][j] = max{dp[t][j - 1] * a[t + 1][i]}

16.codevs 1048 石子归并
有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1]。问安排怎样的合并顺序,能够使得总合并代价达到最小。
dp[i][j]表示从j堆开始合并,i堆石子合并为一堆
dp[i][j] = min{dp[i - 1][j] + dp[1][i + j - 1],dp[i - 2][j] + dp[2][i + j - 2]…}
即 dp[i][j] = min{dp[i - k][j] + dp[k][i + j - k]};
可以用滚动数组

17.codevs 1085 数字游戏
题目大意:在你面前有一圈整数(一共n个),你要按顺序将其分为m个部分,各部分内的数字相加,相加所得的m个结果对10取模后再相乘,最终得到一个数k。游戏的要求是使你所得的k最大或者最小。
dp[i][j][k] 表示i到j分成k个部分的最大值
dp[i][j][k] = max{dp[i][t][k - 1]*dp[t + 1][j][1]};
注意先将环断成链,再将链乘2

18.codevs 1154 能量项链
在项链上有N颗能量珠。能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数。并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记。。如果前一颗能量珠的头标记为m,尾标记为r,后一颗能量珠的头标记为r,尾标记为n,则聚合后释放的能量为mrn(Mars单位),新产生的珠子的头标记为m,尾标记为n。不同的聚合顺序得到的总能量是不同的,请你设计一个聚合顺序,使一串项链释放出的总能量最大。
dp[i][j]表示从j开始合并,将i堆合并成一堆,
dp[i][j] = max{dp[i - k][j] + dp[k][i + j - k] + a[j] * a[j + i - k] * a[j + i]};

19.codevs 2102
典型的石子归并,但此题与原题不同的是:这是一个圆圈,所以我们断环为链,但从哪里断了,最后决定随便断,本题是从1断,再将链延长为2倍

20.洛谷 1470最长前缀 Longest Prefix
有一个字符串S,求他的从s[1]开始的可以被匹配的最长长度。
a[i][k] == j表示第i个字符开始的连续j个字符可以被匹配(即p中有对应的元素)
if( !a[i][k] && !dp[i - a[i][k]]) dp[i] = 1;
注意读入。

21.poj 2385
2棵苹果树在T分钟内随机由某一棵苹果树掉下一个苹果,奶牛站在树#1下等着吃苹果,它最多愿意移动W次,问它最多能吃到几个苹果。
a[i][j] 表示在第j棵树下,前i秒的苹果和
dp[i][j]表示第i秒活动j次可吃到的苹果数
if(j % 2)
{
dp[i][j] = dp[i - 1][j] + a[i][1];
if(j >= 1) dp[i][j] = max(dp[i][j],dp[i - 1][j - 1] + a[i][0]);
}
else
{
dp[i][j] = dp[i - 1][j] + a[i][0];
if(j >= 1) dp[i][j] = max(dp[i][j],dp[i - 1][j - 1] + a[i][1]);
}

22.poj 2355
有n个火车站 告诉你每个火车站的位置, 从s站搭火车到t站, 求最小价格
dp[i]表示第i个车站所需的最小价格
dp[i] = min(dp[i],dp[j] + c) (a[i] - a[j] <= l)

23.poj 1745
给n个数,让他们通过加减运算(第一个不能添加符号),判断结果可不可能被k整除
dp[i][j]表示前i个数通过一系列计算余数能否为j
if(dp[i - 1][j] == 1) dp[i][j + a[j]] = dp[i - 1][j] + a[i]
24.hdu 4526
“拼车”,也就是说,你一个人坐车去,还是一堆人一起,总共需要支付的钱是一样的(每辆出租上除司机外最多坐下4个人)  假设N名Acmer准备拼车,此时为0时刻,从校门到目的地需要支付给出租车师傅D元(按车次算,不管里面坐了多少Acmer),假如S分钟后恰能赶上比赛。现在给出在这S分钟当中经过校门的所有的K辆出租车先后到达校门口的时间Ti 及里面剩余的座位Zi (1 <= Zi <= 4),Acmer可以选择上车几个人(不能超过),当然,也可以选择上0个人,那就是不坐这辆车。  俗话说,时间就是金钱,这里威威猫把每个Acmer在校门等待出租车的分钟数等同于花了相同多的钱(例如威威猫等待了20分钟,那相当于他额外花了20元钱)。
  在保证所有人都能在比赛开始前到达比赛地点的情况下,求最少花多少。.
背包的变式。以k辆车为物品,acmer 为空间。

25.hdu 2154 跳舞毯
小黑买来一块圆形的毯子,把它们分成三等分,分别标上A,B,C,称之为“跳舞毯”,他的运动方式是每次都从A开始跳,每次都可以任意跳到其他块,但最后必须跳回A,且不能原地跳.,小黑跳n次,有天他突然想知道当他跳n次时共几种跳法,算出总共有多少跳法。

有趣的题,有很多状态转移方程,甚至可以直接找规律。
这种题还是老老实实做吧。
dp[i][j]
j=1表示第i步在红色的步数
j=2表示第i步在黄色的步数
j=3表示第i步在蓝色的步数
对于每次跳到红色的状态有:第i-1必须是在蓝色和黄色的地板上
所以dp[i][1]=dp[i-1][2]+dp[i-1][3];
第i步黄色也有dp[i][2]=dp[i-1][1]+dp[i-1][3];
第i步蓝色有dp[i][3]=dp[i-1][1]+dp[i-1][2];

26.poj 2955 && poj 1141 经典区间dp
poj 2955
题目大意:给一个括号序列,问序列中合法的括号最多有多少个
合法的定义:
1.空串是合法的
2.若S是合法的,则[S]和(S)均是合法的 —— 区间dp的提示
3.若A和B是合法的,则AB是合法的

dp[i][j] 表示i到j合法的括号的最大值
dp[i][j] = if(s[i] == s[j])dp[i + 1][j - 1] + 2;
dp[i][j] = dp[i][k] + dp[k + 1][j]

poj 1141
给一些括号,求让它们合法最少要加上多少括号,并输出加上后的结果,
合法的定义:
1.空串是合法的
2.若S是合法的,则[S]和(S)均是合法的
3.若A和B是合法的,则AB是合法的

此题难度稍大于上题 重点在于如何输出最后的结果,评测是sj,递归输出就好

dp[i][j] 表示i到j要添加的括号数
dp[i][j] = if(s[i] == s[j])dp[i + 1][j - 1];
dp[i][j] = min(dp[i][k] + dp[k + 1][j])

27.poj 3280
题目大意是说一个字符串,每插入或者删除一个字符都需要一定的代价,问怎样可以使这个字符串变成一个回文串,且花费最小。
if(s[i] == s[j]) dp[i][j] = dp[i + 1][j - 1];
else dp[i][j] = min(dp[i][j],min(dp[i][j - 1] + t[s[j] - ‘a’],dp[i + 1][j] + t[s[i] - ‘a’]));

28.UVA 10891
n 个数 AB两个人轮流从左或右端取连续的数,
每个人都按最优策略取,A先取,问最后A 比 B 多多少 。
区间DP。
S[i][[j]表示从i到j的数的和,dp[i][j]表示区从i到j的最大先手得分值
dp[i][j] = max(dp[i][j],max(s[i + k][j] - dp[i + k][j] + s[i][i + k - 1],s[i][j - k] - dp[i][j - k] + s[j - k + 1][j]));

s[i + k][j] - dp[i + k][j] + s[i][i + k - 1] 从i开始取到i+k- 1,加上从i+k到j的后手得分值(用总和减去先手得分值)
s[i][j - k] - dp[i][j - k] + s[j - k + 1][j]) 从j –k+1开始取到j,加上从i到j - k的后手得分值(用总和减去先手得分值)
注意枚举时下标是否取等,是否越界。

29.poj 1157
F束花插入V个瓶子里面,花要按编号插,不同花插入不同的花瓶有不同的美观程度,要求最大的美观程度。
dp[i][j]表示第i束花,插进第j个瓶子中的最大值
dp[i][j]=max(dp[i][j],f[i-1][k]+a[i][j]) 1<=k<=j
答案为dp[f][1] 到dp[f][n]中的最大值.

2017.10
30.hdu 1863 prim
typedef pair<int,int> pii;
priority_queue <pii,vector,greater >q;
void prim()
{
dis[1] = 0;q.push(make_pair(dis[1],1));
while(!q.empty())
{
int u = q.top().second;q.pop();
if(vis[u]) continue;vis[u] = 1;ans += dis[u];
for(int i = head[u]; i; i = e[i].next)
{
int v = e[i].v;
if(dis[v] > e[i].w)/
{
dis[v] = e[i].w;
if(!vis[v]) q.push(make_pair(dis[v],v));
}
}
if(++cnt == m) break;
}
if(cnt < m || ans >= inf) printf("?\n");
else printf("%d\n",ans);
}
与dijkstra的最大区别 :prim是当前点v到点集中任一点的最小值,而dijkstra是到起点的最小值

31.Poj 2831 求最小生成树上任意两点间的边的最大值
memset(dis,0x3f3f3f3f,sizeof(dis));
for(int i = 1; i <= n; ++i)
{
fa[i] = i;
end[i] = i;
ns[i].u = ns[i].v = i;
ns[i].next = 0;
head[i] = i;
}
for(int i = 1; i <= m; ++i)
{
int x = find(e[i].u),y = find(e[i].v);//注意不是一个集合
if(x != y)
{
for(a = head[x]; a; a = ns[a].next)
for(b = head[y]; b; b = ns[b].next)
dis[ns[a].v][ns[b].v] = dis[ns[b].v][ns[a].v] = e[i].w;//联通两个并查集的每个点
fa[y] = x;
ns[end[y]].next = head[x];
head[x] = head[y];//将两个并查集合并
if(++cnt == n - 1) break;
}
}

32.poj 1679 次小生成树
代码与上题雷同。
Prim的写法

33.codevs 2597
题目大意:我朋友的朋友是我的朋友。我敌人的敌人也是我的朋友。
并查集操作。
对于敌人的敌人用head[x]保存x的上一个敌人,每次把当前敌人和上一个敌人合并为一个集合。

34.codevs 1001 舒适的路线
题目大意:有N个点,M条边,边是双向的,每条边的速度为v,求s到t的最大速度与最小速度之比。
最优比率生成树
将边权排序后:从前向后,再从后向前找。
int i = start = 1;
while(i <= m)
{
init();
i = start;
while(i <= m)
{
int x = find(e[i].u), y = find(e[i].v);
if(x != y) fa[x] = y;
if(find(s) == find(t))
{
l = i;
maxn = e[i].w;
minn = e[start].w;
if(!maxm)
{
maxm = maxn;
minm = minn;
}
else if(maxn * minm < maxm * minn)
{
maxm = maxn;
minm = minn;
}
break;
}
++i;
}
if(i > m && !maxm)
{
printf(“IMPOSSIBLE\n”);
break;
}
else if(i >= m)
{
int t = gcd(maxm,minm);
maxm /= t;minm /= t;
if(minm != 1) printf("%d/%d\n",maxm,minm);
else printf("%d\n",maxm);
break;
}
init();
while(i > start)
{
int x = find(e[i].u), y = find(e[i].v);
if(x != y) fa[x] = y;
if(find(s) == find(t))
{
maxn = e[l].w;
minn = e[i].w;
if(maxn * minm < maxm * minn)
{
maxm = maxn;
minm = minn;
}
break;
}
–i;
}
start = i + 1;
}
35.topsort
for(int i = 1;i <= n; ++i) if(!in[i]) q.push(i);
while(!q.empty())
{
int u = q.front();q.pop();++ans;
for(int i = head[u]; i != -1; i = e[i].next)
{
int v = e[i].v;
if(!(–in[v])) q.push(v);
}
}
36.rqnoj 389 floyd求最小环
Memset(dp,inf,sizeof(dp);
Memset(a,inf,sizeof(a);
for(int i = 1; i <= m; ++i)
{
scanf("%d%d%d",&u,&v,&w);
a[u][v] = a[v][u] = dp[u][v] = dp[v][u] = w;
}
for(int k = 1; k <= n; ++k)
{
for(int i = 1; i < k; ++i)
for(int j = i + 1; j < k; ++j)
ans = min(ans,dp[i][j] + a[i][k] + a[k][j]);
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j)
dp[i][j] = min(dp[i][j],dp[i][k] + dp[k][j]);
}
Ans即为所求。

37.codevs 2800 送外卖
有一个送外卖的,他手上有n份订单,他要把n份东西,分别送达n个不同的客户的手上。n个不同的客户分别在1~n个编号的城市中。送外卖的从0号城市出发,然后n个城市都要走一次(一个城市可以走多次),最后还要回到0点(他的单位),请问最短时间是多少。现在已知任意两个城市的直接通路的时间。
先跑floyd,再跑状压dp,在进行状压dp时注意初始状态对转移方程的影响。
dp[0][0] = 0;
for(int i = 0;i < s; ++i)
for(int j = 0; j <= n; ++j)
//if(i & (1 << j)) //理论上对于任意i,j,如果dp[i][j]不为inf那么i中包含j,但注意:dp[0][0]位特例,所以这句话不能加
for(int k = 0; k <= n; ++k)
dp[i | (1 << k)][k] = min(dp[i][j] + a[j][k],dp[i|(1 << k)][k]);
for(int i = 1; i <= n; ++i)
ans = min(dp[s - 1][i] + a[i][0],ans);

  1. hdu 2795
    题目大意:一个hw的公告牌,要在其上贴公告。
    • 输入的是1
    wi的w值,这些是公告的尺寸
    • 接下来要满足的条件有:1、尽量往上,同一高度尽量靠左。2、求第n个广告所在的行数。3、没有合适的位置贴了则输出-1。
    把每一行看做线段树上的一个节点,一个节点的len值为此行还剩下的空白(未贴海报的长度)。每次查询去寻找尽量前面的节点的len大于wi的那个节点,使len -= wi.

39.poj 2528 贴海报
题意:n(n<=10000)个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000)。
求出最后还能看见多少张海报。
法1:从后往前贴海报,每贴一张就判断是否被后面的海报覆盖,若覆盖,则此张海报不贴,如果没有全部覆盖,则把没有被覆盖的部分贴上去。
void cover(int x,int y,int k,int num)
{
while(k <= n && x > a[k].r || y < a[k].l) ++k;
if(k > n)
{
a[num].cnt += y - x + 1;
return;
}
if(a[k].l <= x && y <= a[k].r) return;
if(x < a[k].l) cover(x,a[k].l - 1,k + 1,num);
if(a[k].r < y) cover(a[k].r + 1,y,k + 1,num);
}
法2:线段树 +离散化
由于海报范围很大,所以对每个端点进行离散化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值