[题目描述]
有一个整数n(1≤n≤10^9),你需要将n分解成若干互不相等的正数的和。怎么分?
[输入描述]
一行一个数n.
[输出描述]
你需要输出满足条件的分解中最大数的最小值.
[样例输入]
1
[样例输出]
1
膜拜各路神犇。
[题目描述]
有一个整数n(1≤n≤10^9),你需要将n分解成若干互不相等的正数的和。怎么分?
[输入描述]
一行一个数n.
[输出描述]
你需要输出满足条件的分解中最大数的最小值.
[样例输入]
1
[样例输出]
1
难得去一回APIO,结果各种卖萌……
Day 1:上午坐飞机到了北京,下榻,中午吃饺子,我点了2*2两,结果连3两都没吃完,被黄哥哥D……
Day 2:上午听了提交答案题做法(值得听的是怎样截取cheker.exe的内容与怎样在C++中运行cmd,中途说到sprintf("xxx%d%d",a,b);中的sprintf()在cassert库中,我明明经常用这句,可是不知道居然还要这个库……),下午讲了Ural(不是UVa)题目选讲和某场Uva比赛,各种欢乐。
Day 3:去考试了,拿到看完题目后先去做第三道X floyd&bellman,之后觉得第一题模拟可做,就去敲第1题,结果从10点敲到1点(1点30交),终于挑出来了,马不停蹄去写第3题7,8的骗分,赶在’悲惨的白屏-某提交页面崩溃’前交了,Hgh表示最后因为白屏啥也没交上去,只有之前随手交的暴力……
为什么第一题要敲那么久(别人10min暴力)啊,为什么DevC++各种傲娇,缩进各种乱入啊……@#@$#Adsa*
结果成绩出来了:第一题15+第三题52,我是不是应该庆幸好歹自己交上去了?……(早知道去写最后一题X MDj,说不定最后一题还能80多分啊……,第一题交-1就10分好吗?第三题k=1写一下就15分,干嘛把时间都发在模拟上,干嘛打那么久我XX……)
之后评讲走错教室,差点听了一节概率数学各种囧……话外音:什么时候把教室改到101的?
晚上炫教请客吃饭,鱼丸没来,本着膜拜教主,人人有责的原则,不打算让他掏钱,但最后还是掏了(膜拜奖学金2.5*104的)……
找柯黑要了Mingw,从此怒转Codeblocks,从此再也不用担心Dev傲娇。
Day 4:今天刘定峰神犇和天犇组队北大“葫芦杯”ACM,留下我们几个弱菜听讲座。
上午讲了线段树(被虐)。中午和Hgh等人去北大外面吃饭,结果走了10min发现越走越荒凉……无奈掉头,结果我们居然走到了中关村?之后我们到美食广场吃了<?打卤面?>的不明物,回去(已经迟到了,只好用秘籍:go back door.)结果一来就发现居然在打Dota?(我们好像错过了什么),之后讲了团体对抗赛的背景(猩猿星争霸)之所以叫这个名字是因为我们将来从事的某种工作的一个字有关(懂了~够内涵)
明明说要讲数论?之后果断讲了,果断没听懂……<balabala……>
晚上APIO闭幕式发奖状,我考得这么惨居然还能Ag?(Ag垫底……)膜拜福建金牌以及帮他拿奖状的(没来,去看《猩猿争霸》了).
晚上打CF,柯黑神翻译,结果各种错……详见CF 303B
之后我才知道老师找我们一直打不通电话,快急疯了……(明明就在宾馆)
后半夜打《三国杀?》,各种卖队友,不会打三国杀显露无遗……
最后居然快打到天亮了,行李还没整我A&*(&9
Day 5:做飞机回去,中途2人失重。于是天犇去追那2人,老师又叫黄考古去追天犇,之后我去追黄考古被拦(师云:再追人就没了),难以至今的是鱼丸神秘出现在机场大巴上?(它是怎么摸进来的)
于是飞机上又看了一遍《十二生肖》
最近用了很久一段时间的WP,每天尽忙活插件了……
忽然想起大牛Blog的一个共同规律(前面一堆解报,之后好像有点跑题,来点WP相关,OSU,耳机购买策略,怎么磨咖啡,最后很开心的发表其它各类散文/游记/OI心路历程/CF 出题报告(给教主跪烂,给WJMZBMR跪烂……,博客成给别人看的了)
这才发现不同的Bloging方式差别甚远
Blog阶段//
1.Csdn,博客园党:解报解报解报解报解报解报……基本上这种专业Blog会发展成外人看来Orz的Blog狂……实际上只是没做一道题都把代码,题目往上贴,在写2句解题感悟啥的……这种人博客文章是用百计数的,到最后会发展成解报题库(类似Wiki)
2.baidu:在baidu空间升级后各种NTR,转移为WP党……
3.blogbus,点点,Qzone:这种地方真心不适合发解报啊亲……
4.网易,sina:这种地方当当从Blog来说真的不错,毅力指数较高(有很多同党)
Final.Wp党-可以肯定的是前面几种人最后都会陆续迁到这,然后不挪窝了……但是Wp在我看来真心不适合搞解报(之所以这么说是因为使用经验,Wp绝没有一个现成的成体制的社区来的方便,因此你总会感觉是你自己一个人更新,自得其乐,你开始真正领悟啥叫Blog了……)
最后说一句,最好不要在这里发解报[exp]要发左转[/exp]
现在有一个数x,1 ≤ x≤ n,告诉你n,每次你可以猜一个数y,如果x==y则结束,否则返回gcd(x,y),问最少只要几次就可以保证猜出答案。
The input file contains several test cases, each of them as described below.
The input contains one integer n, 2n10000.
For each test case, write to the output on a line by itself.
Output one integer -- the number of guesses Andrew will need to make in the worst case.
6
Sample Output
2
首先把所有n以内素分组,每次询问一组素数的积——根据Gcd的性质确定这个数
每次贪心拿一个大质数与一堆小质数配(最右*最左)
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define MAXN (10000)
#define eps (1e-9)
#define For(i,n) for(int i=1;i< =n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
int n,a[MAXN],size=0;
bool b[MAXN];
int main()
{
memset(b,0,sizeof(b));b[1]=1;
Fork(i,2,MAXN)
{
if (!b[i]) b[i]=1,a[++size]=i;
For(j,size)
{
if (i*a[j]>MAXN) break;
b[i*a[j]]=1;
if (!i%a[j]) break;
}
}
// For(i,100) cout< >n)
{
int i=0,head=1,tail=size;
while (a[tail]>n) tail--;
while (head< =tail)
{
int p=a[tail];
while (p*a[head]<=n) p*=a[head++];
tail--;i++;
}
cout<
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 1181 Solved: 654
高斯消元
显然可以消成Σ(pi-qi)xi=1/2*Σ(pi^2-qi^2)
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define MAXN (10+10)
#define MAXAi (20000)
#define eps (0.0000001)
#define For(i,n) for(int i=1;i< =n;i++)
double sqr(double x){return x*x;}
int n;
double a[MAXN][MAXN],f[MAXN][MAXN]={0.0};
int gauss()
{
For(i,n)
{
if (abs(f[i][i])
swap(f[p],f[i]);//Waiting for change
}
if (abs(f[i][i])
For(i,n+1) For(j,n) cin>>a[i][j];
For(i,n) For(j,n) f[i][j]=a[i][j]-a[i+1][j],f[i][n+1]+=sqr(a[i][j])-sqr(a[i+1][j]);
For(i,n) f[i][n+1]/=2;
/*
For(i,n)
{
For(j,n+1) cout<
从A点到B点走k次,每次只能向左,下,假定每个格子上都有一个整数,问能走过的最大的数的和是多少?
从A点到B点走k次,每次只能向左,下,假定每个格子上都有一个整数,问能走过的最大的数的积是多少?
Problem 3 数位和乘积(digit.cpp/c/pas)
【题目描述】
一个数字的数位和乘积为其各位数字的乘积。求所有的N位数中有多少个数的数位和乘积恰好为K。请注意,这里的N位数是可以有前导零的。比如01,02视为二位数,但是他们的数位和乘积都是0。
【输入格式】
一行两个整数N,K
【输出格式】
一个行一个整数表示结果。
【样例输入】
2 3
【样例输出】
2
【样例输入2】
2 0
【样例输出2】
19
【数据范围】
对于20%:N <= 6。
对于50%:N<=16
存在另外30%:K=0。
对于100%:N <= 50,0 <= K <= 10^9。
法1:
k=0时,ans=10^n-9^n
否则就用记忆化搜索填1..9的个数
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define MAXN (50+10)
#define F (10000)
int n,k;
struct highn
{
int len,a[900];
highn():len(1){memset(a,0,sizeof(a));}
highn(int x)
{
memset(a,0,sizeof(a));
int i=0;
while (x)
{
a[++i]=x%F;
x/=F;
}
len=i;
}
void print()
{
printf("%d",a[len]);
for (int i=len-1;i;i--)
{
// if (a[i]<10000) printf("0");
if (a[i]<1000) printf("0");
if (a[i]<100) printf("0");
if (a[i]<10) printf("0");
printf("%d",a[i]);
}
}
friend highn operator+(highn& a,highn& b)
{
highn c;
int maxlen=max(a.len,b.len);
for (int i=1;i< =maxlen;i++)
{
c.a[i]=c.a[i]+a.a[i]+b.a[i];
if (c.a[i]>F)
{
c.a[i+1]+=c.a[i]/F;
c.a[i]%=F;
}
}
c.len=maxlen+1;
while (!c.a[c.len]&&c.len>1) c.len--;
return c;
}
friend highn operator-(highn& a,highn& b)
{
highn c;
int maxlen=a.len;
for (int i=1;i< =maxlen;i++)
{
c.a[i]+=a.a[i]-b.a[i];
if (c.a[i]<0)
{
c.a[i+1]--;
c.a[i]+=F;
}
}
c.len=maxlen;
while (!c.a[c.len]&&c.len>1) c.len--;
return c;
}
friend highn operator*(highn& a,highn& b)
{
highn c;
for (int i=1;i< =a.len;i++)
{
for (int j=1;j<=b.len;j++)
{
c.a[i+j-1]+=a.a[i]*b.a[j];
if (c.a[i+j-1]>F)
{
c.a[i+j]+=c.a[i+j-1]/F;
c.a[i+j-1]%=F;
}
}
}
c.len=a.len+b.len+1;
while (!c.a[c.len]&&c.len>1) c.len--;
return c;
}
};
highn pow2(highn a,int b)
{
highn c;
if (!b) return 1;
if (b%2)
{
c=pow2(a,b/2);
c=c*c;
c=c*a;
}
else
{
c=pow2(a,b/2);
c=c*c;
}
return c;
}
int a[11],tot,b[11];
highn ans,C[51][51];
void dfs(int deep,highn rel,int hasget)
{
if (n
法2:
f[i][j][k][l][m]表示填到第i个数,2,3,5,7分别用j,k,l,m个的方案数
考虑后面填1..9的情况(显然不可能填0)
Bug:n=50,C(n,m)最大为C(50,25),可用long long.
----
----
法3:
容易发现
k=2^a*3^b*5^c*7^d时才有解
而且5,7取了当且只当数位为5,7的情况.
2-2,4,6,8
3-3,6,9
5-5
7-7
故可只考虑2,3,不考虑5,7
f[i][j]k]表示i位,取了j个2和k个3后的方案数,
因为可以用1填充,
所以答案=∑f[p][j][k]*C(p,j+k)*C(n,a[5])*C(n-a[5],a[7]) (p<=n-a[5]-a[7])
Time Limit: 5 Sec Memory Limit: 162 MB
Submit: 922 Solved: 323
[Submit][Status][Discuss]
这题我是用块状链表做的
块状链表的复杂度大约是O(√n)
一定要尽可能将块分成长度为√tot的,balance()时要把所有的长度分为介于1/2√tot-2√tot之间
另外merge时要注意先把cur移动再重载合并格的长度(不容易查出错,不知为何,加错也能过8个点)
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define MAXP (1024*1024)
#define MAXN (2900)
struct block
{
int n;
char a[MAXN];
block *next,*pre;
block():n(0){next=pre=NULL;}
}*first;
block* q[MAXN];
int size=0,tot=0;
void del(block *x)
{
q[++size]=x;
if (x->pre) x->pre->next=x->next;
if (x->next) x->next->pre=x->pre;
if (x==first) first=x->next;
}
block *newblock()
{
if (size) return q[size--];
block *x=new block();
return x;
}
void link(block *a,block *b)
{
if (a) a->next=b;
if (b) b->pre=a;
}
void spilt(block *x,int nowsize)
{
if (!nowsize||nowsize==x->n) return;
block *tmp=x->next;
x->next=newblock();
block *x2=x->next;
x2->n=x->n-nowsize;
for (int i=1;i< =x2->n;i++) x2->a[i]=x->a[nowsize+i];
x->n=nowsize;
link(x2,tmp);
link(x,x2);
}
struct cursor
{
int n;
block *ll;
cursor():n(0){ll=first; }
void pre()
{
n--;
if (n<0)
{
ll=ll->pre;
n=ll->n-1;
}
}
void next()
{
n++;
if (n>ll->n)
{
ll=ll->next;
n=1;
}
}
void move(int k)
{
n=k,ll=first;
while (n>ll->n)
{
n-=ll->n;
ll=ll->next;
}
}
}cur;
void get(cursor cur,int k)
{
int p=cur.ll->n-cur.n;
if (p>=k)
{
for (int i=cur.n+1;i< =cur.n+k;i++)
printf("%c",cur.ll->a[i]);
}
else
{
for (int i=cur.n+1;i< =cur.ll->n;i++) printf("%c",cur.ll->a[i]);
cur.ll=cur.ll->next;cur.n=0;
get(cur,k-p);
}
}
void merge(block *x)
{
if (!x->next) return;
for (int i=1;i< =x->next->n;i++) x->a[x->n+i]=x->next->a[i];
if (cur.ll==x->next)
{
cur.ll=x;
cur.n+=x->n;
}
x->n+=x->next->n;
del(x->next);
}
void balance()
{
int maxsize=min(MAXN,(int)sqrt(tot)*2);
int minsize=(int)sqrt(tot)/2;
block *x=first;
while (x)
{
while (x->n
{
if (x->n
// get(cur,1);
}
else
{
spilt(x,(x->n)>>1);
if (cur.ll==x&&cur.n>cur.ll->n)
{
cur.n-=cur.ll->n;
cur.ll=cur.ll->next;
}
// get(cur,1);
}
}
x=x->next;
}
}
void delet(int k)
{
if (!k) return;
if (cur.n)
{
spilt(cur.ll,cur.n);
cur.ll=cur.ll->next; cur.n=0;
}
while (k>cur.ll->n)
{
del(cur.ll);
k-=cur.ll->n;
cur.ll=cur.ll->next;
// cur.n=0;
}
if (k==cur.ll->n)
{
cur.ll->n=0;
}
else
{
spilt (cur.ll,k);
delet(k);
}
balance();
}
void insert(int k)
{
block *l=newblock();*l=block();
block *r=l;
int maxsize=min(MAXN,(int)sqrt(tot));
for (int i=1;i< =k;i++)
{
char c;
for (scanf("%c",&c);(c<32)||(c>126)||(c=='\n');scanf("%c",&c));
if (r->n>maxsize)
{
block *tmp=r;
r=newblock();*r=block();link(tmp,r);
}
r->a[++r->n]=c;
}
if (cur.n)
{
spilt(cur.ll,cur.n);
block *tmp=cur.ll->next;
link(cur.ll,l),link(r,tmp);
}
else
{
link(cur.ll->pre,l),link(r,cur.ll),cur.ll=l;
if (first->pre) first=l;
}
balance();
}
int main()
{
first=newblock();cur.ll=first;
int t;scanf("%d",&t);
while (t--)
{
char s[10];
scanf("%s",s);
int k;
switch(s[0])
{
case'M':scanf("%d",&k);cur.move(k);break;
case'I':scanf("%d",&k);tot+=k;insert(k);break;
case'D':scanf("%d",&k);tot-=k;delet(k);break;
case'G':scanf("%d",&k);get(cur,k);printf("\n");break;
case'P':cur.pre();break;
case'N':cur.next();break;
}
// get(cursor(),tot);cout<