news 2026/4/25 3:11:29

洛谷-算法2-1-前缀和、差分与离散化2

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
洛谷-算法2-1-前缀和、差分与离散化2

P1955 [NOI2015] 程序自动分析

题目描述

在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足。

考虑一个约束满足问题的简化版本:假设 x1​,x2​,x3​,⋯ 代表程序中出现的变量,给定 n 个形如 xi​=xj​ 或 xi​=xj​ 的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件同时被满足。例如,一个问题中的约束条件为:x1​=x2​,x2​=x3​,x3​=x4​,x4​=x1​,这些约束条件显然是不可能同时被满足的,因此这个问题应判定为不可被满足。

现在给出一些约束满足问题,请分别对它们进行判定。

输入格式

输入的第一行包含一个正整数 t,表示需要判定的问题个数。注意这些问题之间是相互独立的。

对于每个问题,包含若干行:

第一行包含一个正整数 n,表示该问题中需要被满足的约束条件个数。接下来 n 行,每行包括三个整数 i,j,e,描述一个相等/不等的约束条件,相邻整数之间用单个空格隔开。若 e=1,则该约束条件为 xi​=xj​。若 e=0,则该约束条件为 xi​=xj​。

输出格式

输出包括 t 行。

输出文件的第 k 行输出一个字符串YES或者NO(字母全部大写),YES表示输入中的第 k 个问题判定为可以被满足,NO表示不可被满足。

输入输出样例

输入 #1复制

2 2 1 2 1 1 2 0 2 1 2 1 2 1 1

输出 #1复制

NO YES

输入 #2复制

2 3 1 2 1 2 3 1 3 1 1 4 1 2 1 2 3 1 3 4 1 1 4 0

输出 #2复制

YES NO

说明/提示

【样例解释 1】

在第一个问题中,约束条件为:x1​=x2​,x1​=x2​。这两个约束条件互相矛盾,因此不可被同时满足。

在第二个问题中,约束条件为:x1​=x2​,x1​=x2​。这两个约束条件是等价的,可以被同时满足。

【样例说明 2】

在第一个问题中,约束条件有三个:x1​=x2​,x2​=x3​,x3​=x1​。只需赋值使得 x1​=x2​=x3​,即可同时满足所有的约束条件。

在第二个问题中,约束条件有四个:x1​=x2​,x2​=x3​,x3​=x4​,x4​=x1​。由前三个约束条件可以推出 x1​=x2​=x3​=x4​,然而最后一个约束条件却要求 x1​=x4​,因此不可被满足。

【数据范围】

所有测试数据的范围和特点如下表所示:

测试点编号n 的规模i,j 的规模约定
11≤n≤101≤i,j≤1041≤t≤10e∈{0,1}
2
31≤n≤100
4
51≤n≤105
6
7
81≤n≤1051≤i,j≤109
9
10

实现代码:

#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <cmath> #include <cstdlib> using namespace std; int t,n,f[1000007],book[1000007*3]; struct node{ int x,y,e; }a[1000001]; bool cmp(node a,node b){ return a.e>b.e; } inline void first(int kkk){ for(int i=1;i<=kkk;i++) f[i]=i; } int get(int x){ if(x==f[x]) return x; return f[x]=get(f[x]); } int main(){ scanf("%d",&t); while(t--){ int tot=-1; memset(book,0,sizeof(book)); memset(a,0,sizeof(a)); memset(f,0,sizeof(f)); int flag=1; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d %d %d",&a[i].x,&a[i].y,&a[i].e); book[++tot]=a[i].x; book[++tot]=a[i].y; } sort(book,book+tot); int reu=unique(book,book+tot)-book; for(int i=1;i<=n;++i){ a[i].x=lower_bound(book,book+reu,a[i].x)-book; a[i].y=lower_bound(book,book+reu,a[i].y)-book; } first(reu); sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++){ int r1=get(a[i].x); int r2=get(a[i].y); if(a[i].e){ f[r1]=r2; }else if(r1==r2){ printf("NO\n"); flag=0; break; } } if(flag) printf("YES\n"); } return 0; }

P1884 [USACO12FEB] Overplanting S

题目描述

在一个笛卡尔平面坐标系里(则 X 轴向右是正方向,Y 轴向上是正方向),有 N (1≤N≤1000) 个矩形,第 i 个矩形的左上角坐标是 (x1​,y1​),右下角坐标是 (x2​,y2​)。问这 N 个矩形所覆盖的面积是多少?

注意:被重复覆盖的区域的面积只算一次。

输入格式

第一行,一个整数 N (1≤N≤1000)。

接下来有 N 行,每行描述一个矩形的信息,分别是矩形的 x1​,y1​,x2​,y2​(−108≤x1​,y1​,x2​,y2​≤108)。

输出格式

一个整数,被 N 个矩形覆盖的区域的面积。

输入输出样例

输入 #1复制

2 0 5 4 1 2 4 6 2

输出 #1复制

20

实现代码:

#include <iostream> #include <cstring> #include <cmath> #include <algorithm> #define maxn 1010 using namespace std; long long n,x[maxn],y[maxn],x2[maxn],y2[maxn],side[2*maxn]; int arr[maxn]; long long ans; bool cmp(int a,int b) { return y[a]>y[b]; } int main() { cin >> n; for (int i=0;i<n;i++) { cin >> x[i] >> y[i] >> x2[i] >> y2[i]; side[2*i]=x[i]; side[2*i+1]=x2[i]; } sort(side,side+2*n); ans=0; for (int i=1;i<2*n;i++) { if (side[i-1]==side[i]) continue; int m=0; for (int j=0;j<n;j++) { if (x[j]<=side[i-1] && side[i]<=x2[j]) arr[m++]=j; } sort(arr,arr+m,cmp); long long h=y[arr[0]],d=y2[arr[0]],w=side[i]-side[i-1]; for (int j=1;j<m;j++) { int temp=arr[j]; if (y[temp]>d) { ans+=(h-y[temp])*w; h=y[temp]; } else { ans+=(h-d)*w; h=y[temp]; } if (y2[temp]<d) d=y2[temp]; } ans+=(h-d)*w; } cout << ans << endl; }

P2004 领地选择

题目描述

作为在虚拟世界里统帅千军万马的领袖,小 Z 认为天时、地利、人和三者是缺一不可的,所以,谨慎地选择首都的位置对于小 Z 来说是非常重要的。

首都被认为是一个占地 C×C 的正方形。小 Z 希望你寻找到一个合适的位置,使得首都所占领的位置的土地价值和最高。

输入格式

第一行三个整数 N,M,C,表示地图的宽和长以及首都的边长。

接下来 N 行每行 M 个整数,表示了地图上每个地块的价值。价值可能为负数。

输出格式

一行两个整数 X,Y,表示首都左上角的坐标。保证最优解是唯一的。

输入输出样例

输入 #1复制

3 4 2 1 2 3 1 -1 9 0 2 2 0 1 1

输出 #1复制

1 2

说明/提示

对于 60% 的数据,N,M≤50。

对于 90% 的数据,N,M≤300。

对于 100% 的数据,1≤N,M≤103,1≤C≤min(N,M),每块地价值的绝对值不超过 32767。

实现代码:

#include<bits/stdc++.h> using namespace std; int n,m,c; const int N=1e3+10; int a[N][N],hang[N][N]; long long sum[N][N]; int main(){ cin>>n>>m>>c; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ cin>>a[i][j]; hang[i][j]=a[i][j]+hang[i][j-1]; sum[i][j]=hang[i][j]+sum[i-1][j]; } } long long X,Y,maxn=0; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if((i+c-1>n)||(j+c-1>m)) continue; long long k=sum[i+c-1][j+c-1]+sum[i-1][j-1]-sum[i-1][j+c-1]-sum[i+c-1][j-1]; if(k>maxn){ maxn=k; X=i; Y=j; } } } cout<<X<<" "<<Y; return 0; }

P3017 [USACO11MAR] Brownie Slicing G

题目描述

Bessie 烤了一个长方形的布朗尼,可以看作是一个 R×C 的网格(1≤R≤500;1≤C≤500),由小方块组成。在第 i 行,第 j 列的方块中有 Nij​(0≤Nij​≤4,000)颗巧克力豆。

Bessie 想把布朗尼分成 A×B 块(1≤A≤R;1≤B≤C):每头牛一块。布朗尼的切割方式是先进行 A−1 次水平切割(总是在整数坐标上),将布朗尼分成 A 条带。然后每条带独立地进行 B−1 次垂直切割,也是在整数边界上。其他 A×B−1 头牛各自选择一块布朗尼,剩下最后一块给 Bessie。由于它们很贪心,它们会把巧克力豆最少的一块留给 Bessie。

假设 Bessie 以最优方式切割布朗尼,求 Bessie 能获得的最多巧克力豆数。

例如,考虑一个 5 行 4 列的布朗尼,巧克力豆分布如下:

1 2 2 1 3 1 1 1 2 0 1 3 1 1 1 1 1 1 1 1

Bessie 必须将布朗尼分成 4 条水平带,每条带有两块。Bessie 可以这样切割布朗尼:

1 2 | 2 1 --------- 3 | 1 1 1 --------- 2 0 1 | 3 --------- 1 1 | 1 1 1 1 | 1 1

因此,当其他贪心的牛选择它们的布朗尼块时,Bessie 仍然可以得到 3 颗巧克力豆。

输入格式

* 第 1 行:四个用空格分隔的整数:R,C,A 和 B

* 第 2 行到第 R+1 行:第 i+1 行包含 C 个用空格分隔的整数:Ni1​,...,NiC​

输出格式

* 第 1 行:一个整数:Bessie 在她的布朗尼上能保证获得的最多巧克力豆数

显示翻译

题意翻译

输入输出样例

输入 #1复制

5 4 4 2 1 2 2 1 3 1 1 1 2 0 1 3 1 1 1 1 1 1 1 1

输出 #1复制

3

说明/提示

(由 ChatGPT 4o 翻译)

实现代码:

#include<iostream> #include<cstdio> using namespace std; int r,c,a,b,map[501][501],s[501][501],ans; bool check(int x) { int now=0,num=0; for (int i=1;i<=r;i++) { int dis=0,sum=0; for (int j=1;j<=c;j++) if (dis+(s[i][j]-s[i][j-1])-(s[now][j]-s[now][j-1])<x) dis+=(s[i][j]-s[i][j-1])-(s[now][j]-s[now][j-1]); else { sum++; dis=0; } if (sum>=b) { now=i;num++; } } if (num<a) return 0; return 1; } int main() { cin>>r>>c>>a>>b; for (int i=1;i<=r;i++) for (int j=1;j<=c;j++) cin>>map[i][j]; for (int i=1;i<=r;i++) for (int j=1;j<=c;j++) s[i][j]=s[i-1][j]+s[i][j-1]+map[i][j]-s[i-1][j-1]; int h=0,t=s[r][c]; while (h<=t) { int mid=(h+t)/2; if (check(mid)) { h=mid+1; ans=mid; } else t=mid-1; } cout<<ans; }

P3406 海底高铁

题目描述

该铁路经过 N 个城市,每个城市都有一个站。不过,由于各个城市之间不能协调好,于是乘车每经过两个相邻的城市之间(方向不限),必须单独购买这一小段的车票。第 i 段铁路连接了城市 i 和城市 i+1(1≤i<N)。如果搭乘的比较远,需要购买多张车票。第 i 段铁路购买纸质单程票需要 Ai​ 博艾元。

虽然一些事情没有协调好,各段铁路公司也为了方便乘客,推出了 IC 卡。对于第 i 段铁路,需要花 Ci​ 博艾元的工本费购买一张 IC 卡,然后乘坐这段铁路一次就只要扣 Bi​(Bi​<Ai​) 元。IC 卡可以提前购买,有钱就可以从网上买得到,而不需要亲自去对应的城市购买。工本费不能退,也不能购买车票。每张卡都可以充值任意数额。对于第 i 段铁路的 IC 卡,无法乘坐别的铁路的车。

Uim 现在需要出差,要去 M 个城市,从城市 P1​ 出发分别按照 P1​,P2​,P3​,⋯,PM​ 的顺序访问各个城市,可能会多次访问一个城市,且相邻访问的城市位置不一定相邻,而且不会是同一个城市。

现在他希望知道,出差结束后,至少会花掉多少的钱,包括购买纸质车票、买卡和充值的总费用。

输入格式

第一行两个整数,N,M。

接下来一行,M 个数字,表示 Pi​。

接下来 N−1 行,表示第 i 段铁路的 Ai​,Bi​,Ci​。

输出格式

一个整数,表示最少花费。

输入输出样例

输入 #1复制

9 10 3 1 4 1 5 9 2 6 5 3 200 100 50 300 299 100 500 200 500 345 234 123 100 50 100 600 100 1 450 400 80 2 1 10

输出 #1复制

6394

说明/提示

2 到 3 以及 8 到 9 买票,其余买卡。

对于 30% 数据 M=2。

对于另外 30% 数据 N≤1000,M≤1000。

对于 100% 的数据 M,N≤105,Ai​,Bi​,Ci​≤105。

实现代码:

#include<iostream> using namespace std; char ch; template<class T> inline void rd(T& x) { x = 0; int w = 1; ch = getchar(); while (ch < '0' || ch>'9') { if (ch == '-')w = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + ch - '0'; ch = getchar(); } x = x * w; } int a[100001]; unsigned long long t ,sum; int main() { int n, m,x,y,z; rd(n), rd(m); rd(x); for (int i = 2; i <= m; i++) { rd(y); if (x < y) { a[x]++; a[y]--; } else { a[x]--; a[y]++; } x = y; } for (int i = 1; i < n; i++) { t += a[i]; rd(x),rd(y),rd(z); sum += t * y + z < t * x ? t * y + z : t * x; } cout << sum; return 0; }

P1083 [NOIP 2012 提高组] 借教室

题目描述

在大学期间,经常需要租借教室。大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室。教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样。

面对海量租借教室的信息,我们自然希望编程解决这个问题。

我们需要处理接下来 n 天的借教室信息,其中第 i 天学校有 ri​ 个教室可供租借。共有 m 份订单,每份订单用三个正整数描述,分别为 dj​,sj​,tj​,表示某租借者需要从第 sj​ 天到第 tj​ 天租借教室(包括第 sj​ 天和第 tj​ 天),每天需要租借 dj​ 个教室。

我们假定,租借者对教室的大小、地点没有要求。即对于每份订单,我们只需要每天提供 dj​ 个教室,而它们具体是哪些教室,每天是否是相同的教室则不用考虑。

借教室的原则是先到先得,也就是说我们要按照订单的先后顺序依次为每份订单分配教室。如果在分配的过程中遇到一份订单无法完全满足,则需要停止教室的分配,通知当前申请人修改订单。这里的无法满足指从第 sj​ 天到第 tj​ 天中有至少一天剩余的教室数量不足 dj​ 个。

现在我们需要知道,是否会有订单无法完全满足。如果有,需要通知哪一个申请人修改订单。

输入格式

第一行包含两个正整数 n,m,表示天数和订单的数量。

第二行包含 n 个正整数,其中第 i 个数为 ri​,表示第 i 天可用于租借的教室数量。

接下来有 m 行,每行包含三个正整数 dj​,sj​,tj​,表示租借的数量,租借开始、结束分别在第几天。

每行相邻的两个数之间均用一个空格隔开。天数与订单均用从 1 开始的整数编号。

输出格式

如果所有订单均可满足,则输出只有一行,包含一个整数 0。

否则(订单无法完全满足)输出两行,第一行输出一个负整数 −1,第二行输出需要修改订单的申请人编号。

输入输出样例

输入 #1复制

4 3 2 5 4 3 2 1 3 3 2 4 4 2 4

输出 #1复制

-1 2

说明/提示

【输入输出样例说明】

第 1 份订单满足后,4 天剩余的教室数分别为 0,3,2,3。第 2 份订单要求第 2 天到第 4 天每天提供 3 个教室,而第 3 天剩余的教室数为 2,因此无法满足。分配停止,通知第 2 个申请人修改订单。

【数据范围】

对于 10% 的数据,有 1≤n,m≤10;

对于 30% 的数据,有 1≤n,m≤1000;

对于 70% 的数据,有 1≤n,m≤105;

对于 100% 的数据,有 1≤n,m≤106,0≤ri​,dj​≤109,1≤sj​≤tj​≤n。

NOIP 2012 提高组 第二天 第二题

2022.2.20 新增一组 hack 数据

实现代码:

#include<iostream> #include<cstring> #include<cstdio> using namespace std; int n,m; int diff[1000011],need[1000011],rest[1000011],r[1000011],l[1000011],d[1000011]; bool isok(int x) { memset(diff,0,sizeof(diff)); for(int i=1;i<=x;i++) { diff[l[i]]+=d[i]; diff[r[i]+1]-=d[i]; } for(int i=1;i<=n;i++) { need[i]=need[i-1]+diff[i]; if(need[i]>rest[i])return 0; } return 1; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&rest[i]); for(int i=1;i<=m;i++)scanf("%d%d%d",&d[i],&l[i],&r[i]); int begin=1,end=m; if(isok(m)){cout<<"0";return 0;} while(begin<end) { int mid=(begin+end)/2; if(isok(mid))begin=mid+1; else end=mid; } cout<<"-1"<<endl<<begin; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/25 3:11:09

2026-04-25 全国各地响应最快的 BT Tracker 服务器(移动版)

数据来源&#xff1a;https://bt.me88.top 序号Tracker 服务器地域网络响应(毫秒)1http://211.75.205.189:6969/announce广东佛山移动362http://60.249.37.20:6969/announce广东惠州移动363http://107.189.2.131:1337/announce北京移动1244udp://107.189.7.165:6969/announce北…

作者头像 李华
网站建设 2026/4/25 3:11:01

HPH的构造

桩机的轰鸣声在长三角沿江沿海响起&#xff0c;食品医药生产线的超细研磨环节中有在发生着事情&#xff0c;一个看似神秘的缩写——“HPH”&#xff0c;正悄悄变化着各自行业的施工与生产格局。需要注意的是&#xff0c;在不同的应用场景之下&#xff0c;这个词汇实际上对应着两…

作者头像 李华
网站建设 2026/4/25 3:07:20

Weka回归分析实战:从数据预处理到模型部署

1. 项目概述&#xff1a;Weka中的回归机器学习实战指南在数据科学领域&#xff0c;回归分析是预测连续型变量的经典方法。Weka作为一款开源的机器学习工作台&#xff0c;以其友好的图形界面和丰富的算法库&#xff0c;成为许多从业者快速验证模型的首选工具。不同于Python/R需要…

作者头像 李华
网站建设 2026/4/25 3:03:48

未来3年,这3个AI赛道已经定了

我最近一直在想一件事。Anthropic上个月的年化收入超过了OpenAI。很多人看到这条新闻&#xff0c;觉得不过是个财报数字。但我觉得这是一个信号——一个新产业正式成型的信号。这个产业叫AI编程。先说为什么是Anthropic&#xff0c;不是OpenAIOpenAI体量更大&#xff0c;名气更…

作者头像 李华
网站建设 2026/4/25 2:53:46

高效手机号码定位工具:3分钟实现电话号码地理位置精准查询

高效手机号码定位工具&#xff1a;3分钟实现电话号码地理位置精准查询 【免费下载链接】location-to-phone-number This a project to search a location of a specified phone number, and locate the map to the phone number location. 项目地址: https://gitcode.com/gh_…

作者头像 李华