CF380A Sereja and Prefixes

开始集训了,一直以来状态不是很好,CODE FORCE 跌的跟狗一样, 现在开始补题目,这道题目还不错的,题意咱就不说了,

http://codeforces.com/problemset/problem/380/A

题目要求的有两种操作,一个是加入单独元素,还有一个就是复制原来已经存在的元素再加进去,有点类似于栈,但是操作步骤会有很多步,所以要真用类似于栈的方法做肯定会超时的,这里询问了一下  JayYe 伙伴的想法,最后做出来了,这里的二分查找,跟一个取模寻找元素很有技巧性,因为题目中的复制操作添加的元素肯定是以前存在的,也就是包括单独添加步骤的一个元素,所以可以通过查找出最原先的一段,然后进行取模来寻找出具体的元素输出来


#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>

#define ll long long

#define eps 1e-7

#define inf 0xfffffff
const ll INF = 1ll<<61;

using namespace std;

//vector<pair<int,int> > G;
//typedef pair<int,int > P;
//vector<pair<int,int> > ::iterator iter;
//
//map<ll,int >mp;
//map<ll,int >::iterator p;
//

const int N = 100000 + 5;

ll sum[N];
int s[N],e[N],mark[N];

int cal(int l,int r,ll x) {
	int ans=r;
	int mid;
	while(l <= r) {
		mid = (l+r)/2;
		if(sum[mid] >= x) {
			ans = mid;
			r = mid -1;
		}
		else 
			l = mid + 1;
	}
	return ans;
}

int main() {
	int n,m;
	while(scanf("%d",&m)==1) {
		for(int i=1;i<=m;i++) {
			scanf("%d",&mark[i]);
			if(mark[i] == 1) {
				scanf("%d",&s[i]);
				sum[i] = sum[i-1] + 1;
			}
			else {
				scanf("%d %d",&e[i],&s[i]);
				sum[i] = sum[i-1] + e[i]*s[i];
			}
		}
		scanf("%d",&n);
		ll x;
		for(int i=0;i<n;i++) {
			scanf("%I64d",&x);
			while(1) {
				int cnt=cal(1,m,x);
				if(mark[cnt] == 1) {
					printf("%d ",s[cnt]);
					break;
				}
				else {
					int tmp = x;
					tmp -= sum[cnt-1];
					tmp %= e[cnt];
					if(tmp == 0)
						x=e[cnt];
					else
						x=tmp;
				}
			}
		}
	}
	return EXIT_SUCCESS;
}


CF380A Sereja and Prefixes

上一篇:简单讲讲如何用C#访问Excel文件


下一篇:BRIEF特征描述子