Codeforces 798D Mike and distribution 构造

来源:互联网 发布:java调用ireport报表 编辑:程序博客网 时间:2024/05/29 15:02

点击打开链接

题意:数组a,b共有n个数,n<=1e5,一定有解,构造出序列[p1..pk] k<=[n/2]+1,满足 2*(a[p1]..a[pk]) > Sum(A) && 2*(b[p1]..b[pk]) > Sum(b)
2*(a[p1]..a[pk]) > Sum(A)
a[p1]..a[pk] > a[q1]..a[q(n-k)] (q为剩下的下标),因为一定有解,所以k=[n/2]+1必定有解 
构造:将a从大->小排序后,当n为odd时,先选取A中最大的元素下标,则剩下2k对元素.
(a[1],a[2],a[3],..a[p],a[p+1]..) 当b[p]>b[p+1]时,选下标p即可,当b[p]<b[p+1] 选下标p+1,两种情况的选择使得,数组b显然满足.
a也同样满足,a[p]<a[p+1] 因为a先选了最大 每次没选的元素 都小于上一次所选的元素,则条件满足 
n为偶数,在odd的情况下多选一个就好了 

#include <bits/stdc++.h>using namespace std;const int N=2e5+20;struct node{int id,v;}a[N],b[N];bool cmp(node a,node b){return a.v>b.v; } int n,vis[N];vector<int> ans;int main(){while(cin>>n){for(int i=1;i<=n;i++)scanf("%d",&a[i].v),a[i].id=i;for(int i=1;i<=n;i++)scanf("%d",&b[i].v),b[i].id=i;sort(a+1,a+1+n,cmp);memset(vis,0,sizeof(vis));ans.clear();ans.push_back(a[1].id);vis[a[1].id]=1;for(int i=2;i<=n;i+=2){int p=a[i].id,q=a[i+1].id;if(b[p].v>=b[q].v)ans.push_back(p),vis[p]=1;elseans.push_back(q),vis[q]=1;}cout<<n/2+1<<endl;for(int i=0;i<ans.size();i++)cout<<ans[i]<<' ';cout<<endl;}return 0;} 


0 0
原创粉丝点击