Codeforces Round #223 (Div. 2)
直接按着题目给的方法模拟就好了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <map> 6 #include <algorithm> 7 #include<stack> 8 #define maxlen 1010 9 using namespace std; 10 int n; 11 int num[maxlen]; 12 int main () 13 { 14 while(scanf("%d",&n)!=EOF) 15 { 16 for(int i=0;i<n;++i) 17 scanf("%d",&num[i]); 18 int i=0,j=n-1; 19 int cnt=1; 20 int sum0=0,sum1=0; 21 while(cnt<=n) 22 { 23 if(cnt&1) 24 { 25 if(num[i]>num[j]) 26 { 27 sum0+=num[i]; 28 i++; 29 } 30 else 31 { 32 sum0+=num[j]; 33 j--; 34 } 35 } 36 else 37 { 38 if(num[i]>num[j]) 39 { 40 sum1+=num[i]; 41 i++; 42 } 43 else 44 { 45 sum1+=num[j]; 46 j--; 47 } 48 } 49 cnt++; 50 } 51 printf("%d %d\n",sum0,sum1); 52 53 } 54 55 }
从小到大排序,输出一遍(不相同),统计一下每个值出现的次数,如果出现两次或以上则从大到小倒过来输出一遍
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <map> 6 #include <algorithm> 7 #include<stack> 8 #define maxlen 100010 9 using namespace std; 10 int n; 11 int num[maxlen]; 12 int hashs[maxlen]; 13 int out[maxlen]; 14 int main () 15 { 16 while(scanf("%d",&n)!=EOF) 17 { 18 for(int i=0; i<n; ++i) 19 scanf("%d",&num[i]); 20 sort(num,num+n); 21 memset(hashs,0,sizeof(hashs)); 22 int ans=0; 23 for(int i=0; i<n; ++i) 24 { 25 if(hashs[num[i]]==0) 26 { 27 out[ans++]=num[i]; 28 29 }hashs[num[i]]++; 30 } 31 for(int i=n-1; i>=0; --i) 32 { 33 if(num[i]!=num[n-1]&&hashs[num[i]]>1) 34 { 35 out[ans++]=num[i]; 36 hashs[num[i]]=0; 37 } 38 } 39 printf("%d\n",ans); 40 printf("%d",out[0]); 41 for(int i=1; i<ans; ++i) 42 printf(" %d",out[i]); 43 printf("\n"); 44 } 45 46 }
给你两种操作:
1 x 在数组后面添加一个数x
2 l c 在数组后面添加num[0~l]这个字串c次
询问:给你下标,输出对应的值。
只有当1操作时才真真的存入数组,以2操作使用一定的方法对应到数组真实的下标,
根据题目可以知道最多会使用1操作在后面插入100000个数字,所以可以开一个数组存下。
记录每次插入的区间,1 操作用一个map存(最后询问的下标对应的真实数组下标) 2 操作用vector 存(开始下标,长度,循环次数)
对于每一次询问只要使用二分查找找到该下标对应的区间或者某个点,如果是点,直接返回其map值,对于区间,则映射到新的下标不断缩小下标知道找到真实数组的下标值返回
例如样例得到的vector如下:
(1) (2) (2 1) (3) (5 2) (4)
开始下标 1 2 3 5 6 16
现在要询问下标为8的值,那么先找到区间起始点<=8且最大的区间开始点6 那么新的下标就为 (8-6)%5+1=3 继续找 得到开始点为3 那么新下标为 (3-3)%2+1=1
继续下去发现是一个点 直接返回map[1]=1 那么答案就是num[1]=1
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <map> 6 #include <algorithm> 7 #include<stack> 8 #define maxlen 100010 9 using namespace std; 10 long long num[maxlen]; 11 int l,ll; 12 int n,m; 13 struct node 14 { 15 long long s,len,c; 16 node(long long _s=0,long long _len=0,long long _c=0) 17 { 18 s=_s;len=_len;c=_c; 19 } 20 friend bool operator <(const node &a,const node &b) 21 { 22 return a.s<b.s; 23 } 24 }; 25 vector<node> mp; 26 map<long long, long long >mp1; 27 bool cmp(node a,node b) 28 { 29 return a.s<b.s; 30 } 31 long long Find(long long p) 32 { 33 long long s=0; 34 while(1) 35 { 36 vector<node>::iterator up; 37 if(mp1[p]>0)return mp1[p]; 38 up = upper_bound(mp.begin(),mp.end(),p); 39 if(up<mp.begin()||up>mp.end())break; 40 if(up==mp.begin())return p; 41 up--; 42 long long s = (*up).s; 43 if(p==s)return 1; 44 else p=((p-s)%(*up).len)+1; 45 } 46 return p; 47 } 48 int main () 49 { 50 int cmd,y; 51 long long x; 52 while(scanf("%d",&n)!=EOF) 53 { 54 l=1; 55 long long pos=1; 56 while(n--) 57 { 58 scanf("%d",&cmd); 59 if(cmd==1) 60 { 61 scanf("%I64d",&x); 62 num[l]=x; 63 mp1[pos]=l; 64 l++; 65 pos++; 66 } 67 else if(cmd==2) 68 { 69 scanf("%I64d%d",&x,&y); 70 mp.push_back(node(pos,x,y)); 71 pos+=(x*y); 72 } 73 } 74 sort(mp.begin(),mp.end(),cmp); 75 scanf("%d",&m); 76 while(m--) 77 { 78 scanf("%I64d",&x); 79 long long p =Find(x); 80 printf("%I64d ",num[p]); 81 } 82 printf("\n"); 83 } 84 }