A::::::::::::::::小明的彩灯:(差分)
小明拥有 N 个彩灯,第 i 个彩灯的初始亮度为 ai。
小明将进行 Q 次操作,每次操作可选择一段区间,并使区间内彩灯的亮度 +x(x 可能为负数)。
求 Q 次操作后每个彩灯的亮度(若彩灯亮度为负数则输出 0)。
第一行包含两个正整数 N,Q,分别表示彩灯的数量和操作的次数。
第二行包含 N 个整数,表示彩灯的初始亮度。
接下来 Q 行每行包含一个操作,格式如下:
l r x
,表示将区间 l∼r 的彩灯的亮度 +x。输出共 1 行,包含 N 个整数,表示每个彩灯的亮度。
5 3
2 2 2 1 5
1 3 3
4 5 5
1 1 -100
0 5 5 6 10
对于所有评测数据,1≤N,Q≤5×105,0≤ai≤109,11≤l≤r≤N,−109≤x≤109。
#include
using namespace std;
int n,m;
long long a[500005];
long long b[500005];
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
b[i]=a[i]-a[i-1];
}
for(int i=1;i<=m;i++){
int l,r;
long long x;
cin>>l>>r>>x;
b[l]=b[l]+x;
b[r+1]=b[r+1]-x;
}
for(int i=1;i<=n;i++){
a[i]=b[i]+a[i-1];
}
for(int i=1;i<=n;i++){
if(a[i]<0){
cout<<0<<' ';
}else{
cout<
B::::::::::::::::解立方根:(二分)
给定一个正整数 N,请你求 N 的立方根是多少。
第 1 行为一个整数 T,表示测试数据数量。
接下来的 T 行每行包含一个正整数 N。
1≤T≤105,0≤N≤105。
输出共 T 行,分别表示每个测试数据的答案(答案保留 3 位小数)。
示例 1
输入
3
0
1
8
输出
0.000
1.000
2.000
#include
#include
#include
using namespace std;
int t,n;
double l(int n){
double l=0,r=1e5;
double res=0;
while(r>=l){
double mid=(l+r)/2.0;
if(mid*mid*mid-n>1e-12){
r=mid-0.000001;
}else if(mid*mid*mid-n<-1e-12){
l=mid+0.000001;
res=mid;
}else{
return mid;
}
}
}
int main(){
cin>>t;
for(int i=0;i>n;
printf("%.3lf\n",l(n));
}
return 0;
}
C:::::::::::::::::走迷宫(BFS)
给定一个 N×M 的网格迷宫 G。G 的每个格子要么是道路,要么是障碍物(道路用 1 表示,障碍物用 0 表示)。
已知迷宫的入口位置为(x1,y1),出口位置为 (x2,y2)。问从入口走到出口,最少要走多少个格子。
输入第 1行包含两个正整数 N,M,分别表示迷宫的大小。
接下来输入一个 N×M 的矩阵。若 Gi,j=1 表示其为道路,否则表示其为障碍物。
最后一行输入四个整数x1,y1,x2,y2,表示入口的位置和出口的位置。
1≤N,M≤102,0≤Gi,j≤1,1≤x1,x2≤N,1≤y1,y2≤M。
输出仅一行,包含一个整数表示答案。
若无法从入口到出口,则输出 -1−1。
示例 1
输入
5 5
1 0 1 1 0
1 1 0 1 1
0 1 0 1 1
1 1 1 1 1
1 0 0 0 1
1 1 5 5
输出
8
#include
#include
using namespace std;
int n,m;
int ans;
int a[105][105];
int b[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
bool flage;
int x1,y1,x2,y2;
struct zuo{
int x,y;
int r;
zuo(int xx,int yy,int rr){
x=xx;
y=yy;
r=rr;
}
};
queue q;
bool c[105][105];
bool check(int x,int y){
return x>0&&x<=n&&y>0&&y<=m;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
}
cin>>x1>>y1>>x2>>y2;
q.push(zuo(x1,y1,0));
c[x1][y1]=1;
while(!q.empty()){
int x=q.front().x;
int y=q.front().y;
int r=q.front().r;
q.pop();
if(x==x2&&y==y2){
ans=r;
flage=true;
break;
}
for(int i=0;i<4;i++){
int tx=x+b[i][0];
int ty=y+b[i][1];
if(check(tx,ty)&&a[tx][ty]==1&&!c[tx][ty]){
c[tx][ty]=1;
int rr=r+1;
q.push(zuo(tx,ty,rr));
}
}
}
if(flage){
cout<
D:::::::::::::::::小明的背包(01背包问题)
小明有一个容量为 V 的背包。
这天他去商场购物,商场一共有 NN 件物品,第 ii 件物品的体积为 wi,价值为 vi。
小明想知道在购买的物品总体积不超过 VV 的情况下所能获得的最大价值为多少,请你帮他算算。
输入第 1 行包含两个正整数 N,V,表示商场物品的数量和小明的背包容量。
第 2∼N+1 行每行包含 2 个正整数 w,v,表示物品的体积和价值。
1≤N≤102,1≤V≤103,1≤wi,vi≤103。
输出一行整数表示小明所能获得的最大价值。
示例 1
输入
5 20
1 6
2 5
3 8
5 15
3 3
输出
37
#include
#include
using namespace std;
int n;
int wi[105];
int vi[105];
int dp[105][10005];
int v;
int main(){
cin>>n>>v;
for(int i=1;i<=n;i++){
cin>>wi[i]>>vi[i];
}
for(int i=1;i<=n;i++){
for(int j=1;j<=v;j++){
dp[i][j]=dp[i-1][j];
if(j>=wi[i]){
dp[i][j]=max(dp[i-1][j],dp[i-1][j-wi[i]]+vi[i]);
}
}
}
cout<
E:::::::::::::::::小明的衣服(哈曼夫树)
小明买了 n 件白色的衣服,他觉得所有衣服都是一种颜色太单调,希望对这些衣服进行染色,每次染色时,他会将某种颜色的所有衣服寄去染色厂,第 ii 件衣服的邮费为 ai 元,染色厂会按照小明的要求将其中一部分衣服染成同一种任意的颜色,之后将衣服寄给小明, 请问小明要将 nn 件衣服染成不同颜色的最小代价是多少?
第一行为一个整数 n ,表示衣服的数量。
第二行包括 n 个整数 a1,a2...an 表示第 i 件衣服的邮费为 ai 元。
(1≤n≤105,1≤ai≤109 )
输出一个整数表示小明所要花费的最小代价。
示例 1
输入
5
5 1 3 2 1
输出
25
#include
#include
using namespace std;
long long ans;
priority_queue,greater > q;
int n;
int main(){
cin>>n;
for(int i=0;i>ai;
q.push(ai);
}
while(q.size()!=1){
long long a=q.top();
q.pop();
long long b=q.top();
q.pop();
ans+=a+b;
q.push(a+b);
}
cout<
F:::::::::::::::::蓝桥骑士(LIS求最长递增序列)
小明是蓝桥王国的骑士,他喜欢不断突破自我。
这天蓝桥国王给他安排了 NN 个对手,他们的战力值分别为 a1,a2,...,an,且按顺序阻挡在小明的前方。对于这些对手小明可以选择挑战,也可以选择避战。
身为高傲的骑士,小明从不走回头路,且只愿意挑战战力值越来越高的对手。
请你算算小明最多会挑战多少名对手。
输入第一行包含一个整数 N,表示对手的个数。
第二行包含 N 个整数 a1,a2,...,an,分别表示对手的战力值。
1≤N≤3×105,1≤ai≤109。
输出一行整数表示答案。
示例 1
输入
6
1 4 2 2 5 6
输出
4
#include
#include
using namespace std;
int n;
long long a[300005];
long long dp[300005];
long long LIS(int n){
dp[1]=a[1];
int ans=2;
for(int i=2;i<=n;i++){
if(dp[ans-1]>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
cout<
G:::::::::::::::::蓝桥幼儿园(并查集)
蓝桥幼儿园的学生是如此的天真无邪,以至于对他们来说,朋友的朋友就是自己的朋友。
小明是蓝桥幼儿园的老师,这天他决定为学生们举办一个交友活动,活动规则如下:
小明会用红绳连接两名学生,被连中的两个学生将成为朋友。
小明想让所有学生都互相成为朋友,但是蓝桥幼儿园的学生实在太多了,他无法用肉眼判断某两个学生是否为朋友。于是他起来了作为编程大师的你,请你帮忙写程序判断某两个学生是否为朋友(默认自己和自己也是朋友)。
第 1 行包含两个正整数 N,M,其中 N 表示蓝桥幼儿园的学生数量,学生的编号分别为 1∼N。
之后的第 2∼M+1 行每行输入三个整数,op,x,y:
1≤N,M≤2×105,1≤x,y≤N。
对于每个 op=2 的输入,如果 x 和 y 是朋友,则输出一行 YES
,否则输出一行 NO
。
示例 1
输入
5 5
2 1 2
1 1 3
2 1 3
1 2 3
2 1 2
输出
NO
YES
YES
#include
using namespace std;
int n,m;
int rel[200005];
int find(int x){
if(rel[x]==x) return x;
return rel[x]=find(rel[x]);
}
void jiaru(int x,int y){
int x1=find(x);
int y1=find(y);
if(x1!=y1){
rel[x1]=y1;
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
rel[i]=i;
}
for(int i=1;i<=m;i++){
int op,x,y;
cin>>op>>x>>y;
if(op==1){
jiaru(x,y);
}else{
if(find(x)==find(y)){
cout<<"YES"<
H:::::::::::::::::蓝桥幼儿园(并查集)
小明在练习绝世武功, n 个练功桩排成一排,一开始每个桩的损伤为 0。
接下来小明会练习 m 种绝世武功,每种武功都会对 [l,r] 区间分别造成 [s,e] 的伤害。
这个伤害是一个等差序列。例如 l=1,r=4,s=2,e=8 ,则会对 1−4 号练功桩造成2,4,6,8 点损伤。
小明想让你统计一下所有练功桩的损伤的和。
第一行输入 n,m,代表练功桩的数量和绝世武功的种类数。
接下来 m 行输入 4 个整数 l,r,s,e 。
1≤n≤107,1≤m≤3×105,1≤l,r≤n
输出一个整数代表所有练功桩的损伤和, 题目保证所有输入输出都在 [[0,9×1018]
示例 1
输入
6 2
1 5 2 10
2 4 1 1
输出
33
#include
using namespace std;
//绝世武功(二阶差分数组)
typedef long long ll;
ll n,m,d,ans;//d:[s,e]公差
ll a[10000005],d1[10000005],d2[10000005];
//一阶差分数组d1,二阶差分数组d2
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++){
ll l,r,s,e;
cin>>l>>r>>s>>e;
d=(e-s)/(r-l);//求出公差
d2[l]= d2[l]+s;
d2[l+1]=d2[l+1]+d-s;
d2[r+1]=d2[r+1]-d-e;
d2[r+2]=d2[r+2]+e;
}
for(int i=1;i<=n;i++){
d1[i]=d1[i-1]+d2[i];
a[i]=a[i-1]+d1[i];
ans+=a[i];
}
cout<
I:::::::::::::::::蓝桥侦探(种类并查集)
小明是蓝桥王国的侦探。
这天,他接收到一个任务,任务的名字叫分辨是非,具体如下:
蓝桥皇宫的国宝被人偷了,犯罪嫌疑人锁定在 N 个大臣之中,他们的编号分别为 1∼N。
在案发时这 N 个大臣要么在大厅1,要么在大厅2,但具体在哪个大厅他们也不记得了。
审讯完他们之后,小明把他们的提供的信息按顺序记了下来,一共 M条,形式如下:
x y
,表示大臣 xx 提供的信息,信息内容为:案发时他和大臣 y不在一个大厅。小明喜欢按顺序读信息,他会根据信息内容尽可能对案发时大臣的位置进行编排。
他推理得出第一个与先前信息产生矛盾的信息提出者就是偷窃者,但推理的过程已经耗费了他全部的脑力,他筋疲力尽的睡了过去。作为他的侦探助手,请你帮助他找出偷窃者!
第 1 行包含两个正整数 N,M,分别表示大臣的数量和口供的数量。
之后的第 2∼M+1 行每行输入两个整数 x,y,表示口供的信息。
1≤N,M≤5×105,1≤x,y≤N。
输出仅一行,包含一个正整数,表示偷窃者的编号。
示例 1
输入
4 5
1 2
1 3
2 3
3 4
1 4
输出
2
#include
using namespace std;
int n,m;
int ans;
int a[10000005];
int find(int x){
if(a[x]==x) return x;
return a[x]=find(a[x]);
}
void jiaru(int x,int y){
int tx=find(x);
int ty=find(y);
if(tx!=ty){
a[tx]=ty;
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=2*n;i++){
a[i]=i;
}
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
if(ans){
break;
}
if(find(x)==find(y)||find(x+n)==find(y+n)){
ans=x;
}
jiaru(x,y+n);
jiaru(y,x+n);
}
cout<
J:::::::::::::::::最长公共子序列(LCS)
给定一个长度为 N 数组 a 和一个长度为 M 的数组 b。
请你求出它们的最长公共子序列长度为多少。
输入第一行包含两个整数 N,M,分别表示数组 a 和 b 的长度。
第二行包含 N 个整数 a1,a2,...,an。
第三行包含 M 个整数b1,b2,...,bn。
1≤N,M≤103,1≤ai,bi≤109。
输出一行整数表示答案。
示例 1
输入
5 6
1 2 3 4 5
2 3 2 1 4 5
输出
4
#include
#include
using namespace std;
long long a[1005];
long long b[1005];
int n,m;
long long dp[1005][1005];
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int j=1;j<=m;j++){
cin>>b[j];
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i]==b[j]){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
cout<
K:::::::::::::::::123(前缀和)
小蓝发现了一个有趣的数列,这个数列的前几项如下:
1,1,2,1,2,3,1,2,3,4,⋯
小蓝发现,这个数列前 11 项是整数 1,接下来 2 项是整数 1 至 2,接下来 3 项是整数 1 至 3,接下来 4 项是整数 1 至 4,依次类推。
小蓝想知道,这个数列中,连续一段的和是多少。
输入的第一行包含一个整数 T,表示询问的个数。
接下来 T 行,每行包含一组询问,其中第 ii 行包含两个整数 li 和 ri,表示询问数列中第 li 个数到第 ri 个数的和。
输出 T 行,每行包含一个整数表示对应询问的答案。
示例
输入
3
1 1
1 3
5 8
输出
1
4
8
#include
using namespace std;
int t;
long long sum1[1500000];
long long qiuhe(long long x) {
return (1+x)*x/2;
}
long long sum(long long x){
if(x==0) return 0;
long long l=0,r=1500000;
while(r>=l){
long long mid=(l+r)>>1;
if(qiuhe(mid)>x){
r=mid-1;
}else{
l=mid+1;
}
}
return sum1[r]+qiuhe(x-qiuhe(r));
}
int main(){
cin>>t;
long long c,len=0;
for(long long i=1;len<=1e12;i++){
sum1[i]=sum1[i-1]+qiuhe(i);
len+=i;
// c=i;
}
// cout<>l>>r;
cout<
K:::::::::::::::::美丽的区间(尺取法)
给定一个长度为 n 的序列 a1,a2,⋯,an 和一个常数 S。
对于一个连续区间如果它的区间和大于或等于 S,则称它为美丽的区间。
对于一个美丽的区间,如果其区间长度越短,它就越美丽。
请你从序列中找出最美丽的区间。
第一行包含两个整数 n,S,其含义如题所述。
接下来一行包含 n 个整数,分别表示a1,a2,⋯,an。
0≤N≤105,1×ai≤104,1≤S≤108。
输出共一行,包含一个整数,表示最美丽的区间的长度。
若不存在任何美丽的区间,则输出 0。
示例 1
输入
5 6
1 2 3 4 5
输出
2
#include
using namespace std;
int n,s;
int a[1000005];
int ans=1e9;
int main(){
cin>>n>>s;
for(int i=0;i>a[i];
}
int l=0,r=0;
int m=0;
while(r=s){
ans=min(ans,r-l);
m=m-a[l];
l++;
}
}
if(ans==1e9){
cout<<0;
return 0;
}
cout<