E1. Array and Segments (Easy version)(暴力) && E2. Array and Segments (Hard version)(线段树维护)
题目链接:
E1:http://codeforces.com/contest/1108/problem/E1
E2:http://codeforces.com/contest/1108/problem/E2
题目大意:
给你n个数,然后给你m个区间,每一个区间代表将给定的n个数这个区间内都减去1,每个区间最多使用一次。然后问你使用哪些区间能够使得这n个数中最大数和最小的差值最大?
首先对于E1:这么小的数据不暴力搞啥??直接问枚举就完事了,每一次枚举的时候保持一个数不变,假设当前的数是最大的,然后其他的只要是不包含这个数的区间,都减去,这样就能让最小的那个位置尽可能的小了。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 # define ll long long 4 # define inf 0x3f3f3f3f 5 const int maxn = 400+100; 6 int a[maxn],b[maxn],sto[maxn]; 7 struct node 8 { 9 int le; 10 int ri; 11 } q[maxn]; 12 int main() 13 { 14 int n,m; 15 scanf("%d %d",&n,&m); 16 for(int i=1; i<=n; i++) 17 { 18 scanf("%d",&a[i]); 19 } 20 for(int i=1; i<=m; i++) 21 { 22 scanf("%d %d",&q[i].le,&q[i].ri); 23 } 24 int maxx=-inf,id=0; 25 for(int i=1; i<=n; i++) 26 { 27 int t1=-inf,t2=inf; 28 for(int j=1; j<=n; j++) 29 { 30 b[j]=a[j]; 31 } 32 for(int j=1; j<=m; j++) 33 { 34 if(i>=q[j].le&&i<=q[j].ri) 35 continue; 36 for(int k=q[j].le; k<=q[j].ri; k++) 37 { 38 b[k]-=1; 39 } 40 } 41 for(int j=1; j<=n; j++) 42 { 43 t1=max(t1,b[j]); 44 t2=min(t2,b[j]); 45 } 46 if(t1-t2>maxx) 47 { 48 maxx=t1-t2; 49 id=i; 50 } 51 } 52 // cout<<m<<endl; 53 printf("%d\n",maxx); 54 int num=0; 55 // cout<<1<<" "<<num<<endl; 56 for(int i=1; i<=m; i++) 57 { 58 if(id>=q[i].le&&id<=q[i].ri) 59 continue; 60 // cout<<1<<endl; 61 sto[++num]=i; 62 } 63 // cout<<2<<" "<<num<<endl; 64 printf("%d\n",num); 65 for(int i=1; i<=num; i++) 66 { 67 if(i==1) 68 printf("%d",sto[i]); 69 else 70 printf(" %d",sto[i]); 71 } 72 printf("\n"); 73 return 0; 74 }
其次对于E2:我们可以寻找最小的数的位置,这个时候为什么不和E1一样去找最大的数的位置呢?因为我们要利用区间的性质,对于每一个节点,我们需要从第一个位置开始。
对于当枚举到第i个节点的时候,需要把包括i的区间都给整上,这个时候求一下最值之差,当枚举到第i+1个节点的时候,我们只需要把不包括第i个节点但是包括第i+1个节点的区间给整上就可以了,这样就能省去很多不必要的操作了。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 # define ll long long 4 # define inf 0x3f3f3f3f 5 # define lson l,m,rt<<1 6 # define rson m+1,r,rt<<1|1 7 const int maxn = 1e5+200; 8 int minn[maxn<<2],maxx[maxn<<2],dif[maxn<<2]; 9 int lazy[maxn<<2]; 10 struct node 11 { 12 int le; 13 int ri; 14 } edge[500+10]; 15 int sto[maxn]; 16 int ans1,ans2; 17 vector<int>q1[maxn],q2[maxn]; 18 void up(int rt) 19 { 20 minn[rt]=min(minn[rt<<1],minn[rt<<1|1]); 21 maxx[rt]=max(maxx[rt<<1],maxx[rt<<1|1]); 22 dif[rt]=maxx[rt]-minn[rt];// 本来查找最值得差的时候是直接询问到底部的,加了这个就不需要了,学到了!! 23 } 24 void build(int l,int r,int rt) 25 { 26 if(l==r) 27 { 28 int tmp; 29 scanf("%d",&tmp); 30 minn[rt]=tmp; 31 maxx[rt]=tmp; 32 return ; 33 } 34 int m=(l+r)>>1; 35 build(lson); 36 build(rson); 37 up(rt); 38 } 39 void down(int rt) 40 { 41 if(lazy[rt]) 42 { 43 lazy[rt<<1]+=lazy[rt]; 44 lazy[rt<<1|1]+=lazy[rt]; 45 minn[rt<<1]+=lazy[rt]; 46 minn[rt<<1|1]+=lazy[rt]; 47 maxx[rt<<1]+=lazy[rt]; 48 maxx[rt<<1|1]+=lazy[rt]; 49 lazy[rt]=0; 50 } 51 } 52 void update(int l,int r,int rt,int L,int R,int p) 53 { 54 if(L<=l&&R>=r) 55 { 56 minn[rt]+=p; 57 maxx[rt]+=p; 58 lazy[rt]+=p; 59 return ; 60 } 61 down(rt); 62 int m=(l+r)>>1; 63 if(L<=m) 64 update(lson,L,R,p); 65 if(R>m) 66 update(rson,L,R,p); 67 up(rt); 68 } 69 //int querymax(int l,int r,int rt) 70 //{ 71 // if(l==r) 72 // { 73 // return maxx[rt]; 74 // } 75 // int t1; 76 // down(rt); 77 // int m=(l+r)>>1; 78 // if(l<=m)querymax(lson); 79 // if(r>m)querymax(rson); 80 // up(rt); 81 //} 82 //void querymin(int l,int r,int rt) 83 //{ 84 // if(l==r) 85 // { 86 // ans2=min(ans2,minn[rt]); 87 // return ; 88 // } 89 // down(rt); 90 // int m=(l+r)>>1; 91 // querymin(lson); 92 // querymin(rson); 93 // up(rt); 94 //} 95 int main() 96 { 97 int n,m,tmp,len; 98 scanf("%d %d",&n,&m); 99 build(1,n,1); 100 int ans=-inf,id=0; 101 for(int i=1; i<=m; i++) 102 { 103 scanf("%d %d",&edge[i].le,&edge[i].ri); 104 q1[edge[i].le].push_back(i); 105 q2[edge[i].ri].push_back(i); 106 } 107 for(int i=1; i<=n; i++) 108 { 109 len=q2[i-1].size(); 110 for(int j=0; j<len; j++) 111 { 112 tmp=q2[i-1][j]; 113 update(1,n,1,edge[tmp].le,edge[tmp].ri,1); 114 } 115 len=q1[i].size(); 116 for(int j=0; j<len; j++) 117 { 118 tmp=q1[i][j]; 119 update(1,n,1,edge[tmp].le,edge[tmp].ri,-1); 120 } 121 if(ans<dif[1]) 122 { 123 ans=dif[1]; 124 id=i; 125 } 126 } 127 int num=0; 128 printf("%d\n",ans); 129 for(int i=1; i<=m; i++) 130 { 131 if(edge[i].le<=id&&edge[i].ri>=id) 132 { 133 sto[++num]=i; 134 } 135 } 136 printf("%d\n",num); 137 for(int i=1; i<=num; i++) 138 { 139 if(i==1) 140 printf("%d",sto[i]); 141 else 142 printf(" %d",sto[i]); 143 } 144 printf("\n"); 145 return 0; 146 }