http://codeforces.com/contest/66題目不是很難,為啥比賽時(shí)狀態(tài)那么差...
A 判斷BigInteger可以用string來判斷就行了,不用大整數(shù)
B 水
C 建樹
D我的那種構(gòu)造方法肯定要大整數(shù)的,太懶了,居然不上java
E單調(diào)隊(duì)列,之前做過類似的,sample畫錯(cuò)... T_T
D

/**//*
構(gòu)造n個(gè)數(shù),使得兩兩不互素,但所有數(shù)互素
其實(shí)只要前3個(gè)數(shù)互素就行了!!!
后面的數(shù)隨便構(gòu)造,跟前面同一個(gè),有g(shù)cd>1
如6 10 15
后面的就20,30

比賽時(shí),很囧
我是用前面n個(gè)素?cái)?shù)去構(gòu)造
a[i] = pr[1]*
*p[n] / p[i]
早就超long long
我偷懶不想java,以為不會(huì)超
T_T
*/
#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
#include<stack>
#include<queue>
#include<cmath>
#include<string>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<set>
#include<list>
#include<numeric>
#include<cassert>
#include<ctime>

using namespace std;


int main()


{
#ifndef ONLINE_JUDGE
//freopen("in","r",stdin);
#endif


for(int n; ~scanf("%d", &n); )
{

if(n <= 2)
{
cout<<-1<<endl;
continue;
}
cout<<6<<endl<<10<<endl<<15<<endl;

for(int i = 3 ; i < n ; i++)
{
cout<<10*(i-1)<<endl;
}
}
return 0;
}
E

/**//*
n個(gè)頂點(diǎn)連接成一個(gè)環(huán) n<=10^6
在每個(gè)點(diǎn)出能加油a[i],i到i+1需耗油b[i]
問有多少個(gè)點(diǎn)可以作為起點(diǎn),使得順時(shí)針或逆時(shí)針可以走完一圈
可以走完一圈也即油要足夠了
考慮順時(shí)針的
令num[i] = a[i] - b[i]
sum[i] = ∑num[j] i<=j<=n
若點(diǎn)start可以作為起點(diǎn),則必有
sum[start] - sum[start+1] >= 0
sum[start] - sum[start+2] >= 0

sum[start] - sum[start+n] >= 0
也即min{sum[start] - sum[j]} >= 0 , sum[start] - max{sum[j]} >= 0
start+1<=j<=start+n
對(duì)于式子sum[start] - max{sum[j]} >= 0 就可以用單調(diào)隊(duì)列來做了
維護(hù)一個(gè)單調(diào)遞減的序列,隊(duì)首就是最大值了

跟hdu 3474類似
*/
#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
#include<stack>
#include<queue>
#include<cmath>
#include<string>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<set>
#include<list>
#include<numeric>
#include<cassert>
#include<ctime>

using namespace std;

const int MAXN = 100861;

int a[MAXN], b[MAXN];
int num[MAXN*2];
int dq[MAXN];
long long sum[MAXN*2];
bool can[MAXN];

int main()


{
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
#endif


for(int n; ~scanf("%d",&n); )
{

for(int i = 1 ; i <= n ; i++)
{
scanf("%d",&a[i]);
}

for(int i = 1 ; i <= n ; i++)
{
scanf("%d",&b[i]);
}
fill(can+1, can+1+n, false);


//min{sum[i] - sum[j]} >= 0
//sum[i] - max{sum[j]} >= 0

//mantain a decreasing sequence

//clockwise

for(int i = 1 ; i <= n ; i++)
{
num[i] = num[i+n] = a[i] - b[i];
}
sum[2*n+1] = 0;
int front = 0, tail = 0;

for(int i = 2*n ; i > n ; i--)
{
sum[i] = sum[i+1] + num[i];
while( front < tail && sum[dq[tail-1]] <= sum[i] )tail--;
dq[tail++] = i;
}

for(int i = n ; i > 0 ; i--)
{
sum[i] = sum[i+1] + num[i];
while(front < tail && dq[front] > i + n )front++;

if(sum[dq[front]] <= sum[i])
{
can[i] = true;
}
while( front < tail && sum[dq[tail-1]] <= sum[i] )tail--;
dq[tail++] = i;
}
//counter-clockwise

for(int i = 1 ; i <= n ; i++)
{//注意是a[i] - b[i-1] !!!
num[i] = num[i+n] = a[i] - b[i > 1 ? i - 1 : n];
}
sum[0] = 0;
front = 0, tail = 0;

for(int i = 1 ; i <= n ; i++)
{
sum[i] = sum[i-1] + num[i];
while( front < tail && sum[dq[tail-1]] <= sum[i] )tail--;
dq[tail++] = i;
}

for(int i = n+1 ; i <= 2*n ; i++)
{
sum[i] = sum[i-1] + num[i];
while(front < tail && dq[front] < i - n )front++;

if(sum[dq[front]] <= sum[i])
{
can[i-n] = true;
}
while( front < tail && sum[dq[tail-1]] <= sum[i] )tail--;
dq[tail++] = i;
}

int ans = count(can+1,can+1+n,true);
printf("%d\n",ans);
bool blank = false;

for(int i = 1 ; i <= n ; i++)
{

if(can[i])
{

if(blank)
{
putchar(' ');
}
printf("%d",i);
blank = true;
}
}
puts("");
}
return 0;
}