https://www.acwing.com/activity/content/problem/content/334/
参考代码:
1 //差分的性质运用和基本思维 2 //差分就不多说了基本操作 3 //题目要求得到的数都一样的最小操作次数,我们在求出差分数组之后可以进行如下操作 4 //因为我们最终目的是使得cf[2]~cf[N+1]都是0,a[1]=cf[1] 5 //所以说第一步肯定是尽量中和差分数组中的正负数,这种的是2<=i,j<=n 6 //第二种操作是修改a[i]的前缀,即i=1,2<=j<=n,就是让cf[1]+1,cf[j]-=1,那他只能让修改差分数组cf[j]一个数而已 7 //第三种操作是修改a[i]的后缀,即2<=i<=n,j=n+1,同上,也只能修改cf[i]种的一个数而已 8 //第四种是修改a[i]全部,即i=1,j=n+1这种没有操作意义所以说不要选这种操纵 9 //因此,现在的核心想法就是如何运用上述的三种操作,可以更快用更少的操作取完成我们的目标。从直觉上看,我们应该多用第一种操作, 10 //因为第一种操作它一次可以改变差分数组的两个数,而第二、三种操作,它一次只能改变差分数组中的一个数。 11 //那就很明确了,正数和负数中和需要min(zs,fs)次,还剩下abs(zs-fs)次,剩下的这些既可以与cf[1]配对 12 //也可以与cf[n+1]配对,即执行操作二三来修改他们,因此总次数是min(zs,fs)+abs(zs-fs)=max(zs,fs) 13 //至于产生序列的种数,我们知道,修改后序列的种数很明显是由cf[1]决定的,还剩下的abs(zs-fs)中,既可以与cf[1]配对 14 //也可以与cf[n+1]配对,那么cf[1]就可以分配0,1,2.....abs(zs-fs)个,同理cf[n+1]可分配abs(zs-fs),......1,0个,即操作二我们会修改 15 //cf[1]的值,如果我们进行abs(zs-fs)+1个不同的序列次操作二,就会有abs(zs-fs)+1个不同的序列 16 //所以说综上所述要达到所有数都相等的总次数是min(zs,fs)+abs(zs-fs)=max(zs,fs) 17 //产生不同的序列的种数是abs(zs-fs)+1个 18 #include<bits/stdc++.h> 19 using namespace std; 20 #define int long long 21 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); 22 const int N=1e5+10; 23 int a[N]; 24 int n; 25 inline int read(){ 26 int s=0,w=1;char ch=getchar(); 27 while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();} 28 while(ch>='0'&&ch<='9')s=(s<<1)+(s<<3)+ch-'0',ch=getchar(); 29 return s*w; 30 } 31 inline void write(int x) 32 { 33 if (x < 0) putchar('-'), x = -x; 34 if(x > 9) 35 write(x / 10); 36 putchar(x % 10 + '0'); 37 return; 38 } 39 signed main() 40 { 41 IOS; 42 n=read(); 43 for(int i=1;i<=n;i++) 44 { 45 a[i]=read(); 46 //a[i]-=a[i-1]; 47 //cout<<a[i]<<" "; 48 } 49 //cout<<endl; 50 int zs=0; 51 int fs=0; 52 for(int i=2;i<=n;i++) 53 { 54 int t=a[i]-a[i-1]; 55 if(t>0) 56 { 57 zs+=t; 58 } 59 else 60 { 61 fs-=t; 62 } 63 } 64 cout<<max(zs,fs)<<endl; 65 cout<<abs(zs-fs)+1<<endl; 66 return 0; 67 }
https://www.acwing.com/activity/content/problem/content/335/
参考代码:
1 //差分优化和+区间的处理问题 2 //m对关系其实表示的就是牛与牛之间的相对高度 3 //我们设每对关系中的牛的身高是a,b(b>a),a与b能相互看见表示从下标ai+1到b-1的数都要--,因为ab两头牛 4 //比他们中间其余的牛的身高都要高,其余牛的身高至少要比a,b小1 5 //另外c[p]肯定是为0的 6 //于是我们思路就确定了,但是很现实的是这里每对关系都相当于一个区间,如果直接对c数组操作的复杂度是o(nm) 7 //看一下数据就知道会不会爆了 8 //这里用差分数组来优化一下,区间的数都加上或者减去一个数表示对差分数组的操作(不说了) 9 //最后求一下前缀和,用h+c[i]就是每头牛的身高了 10 //蓝书的题目真的是宝藏题目 11 #include<bits/stdc++.h> 12 using namespace std; 13 #define int long long 14 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); 15 const int N=5e3+10; 16 int n,p,h,m; 17 int a[N]; 18 int d[N];//差分数组 19 int c[N];//表示比最高的牛矮多少 20 map<pair<int,int>,int>s; 21 inline int read(){ 22 int s=0,w=1;char ch=getchar(); 23 while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();} 24 while(ch>='0'&&ch<='9')s=(s<<1)+(s<<3)+ch-'0',ch=getchar(); 25 return s*w; 26 } 27 inline void write(int x) 28 { 29 if (x < 0) putchar('-'), x = -x; 30 if(x > 9) 31 write(x / 10); 32 putchar(x % 10 + '0'); 33 return; 34 } 35 signed main() 36 { 37 IOS; 38 n=read(),p=read(),h=read(),m=read(); 39 int x,y; 40 for(int i=1;i<=m;i++) 41 { 42 x=read(),y=read(); 43 if(x>y) 44 { 45 swap(x,y); 46 } 47 if(s[make_pair(x,y)]) 48 continue; 49 d[y]++; 50 d[x+1]--; 51 s[make_pair(x,y)]=1; 52 } 53 for(int i=1;i<=n;i++) 54 { 55 c[i]=c[i-1]+d[i]; 56 cout<<h+c[i]<<endl; 57 } 58 return 0; 59 }
标签:10,ch,int,差分,read,数组,两道 From: https://www.cnblogs.com/LQS-blog/p/17044821.html