51nod算法马拉松14

这次太丢人了只搞出来了A到D,那就将就写一写A到D。。。

A 棋盘问题

脑筋急转弯题,不难发现每一次两个人只能染白奇数个格子,所以数数有奇数还是偶数个白格子就行了。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
using namespace std;
inline int read() {
    int x=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c==‘-‘) f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘;
    return x*f;
}
typedef long long ll;
const int maxn=110;
int n,m;
void solve() {
	n=read();m=read();int is=0;
	rep(i,1,n) rep(j,1,m) is+=read();
	puts((is&1)?"yadang":"xiawa");
}
int main() {
	dwn(T,read(),1) solve();
	return 0;
}

B 约数和

不难发现b=1*a,c=1*b,即c=1*1*a,这里都是数论卷积。

预处理1*1,然后对于每个修改暴力更改影响的ci,期望每次修改是O(logn)的。

但是这道题卡常数。但是这道题卡常数。但是这道题卡常数。

最后上uoj拿来一份高级IO优化才过2333。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
using namespace std;
typedef long long ll;
const int BufferSize=1<<16;
char buffer[BufferSize],*head,*tail;
inline char Getchar() {
    if(head==tail) {
        int l=fread(buffer,1,BufferSize,stdin);
        tail=(head=buffer)+l;
    }
    return *head++;
}
inline int read() {
    int x=0,f=1;char c=Getchar();
    for(;!isdigit(c);c=Getchar()) if(c==‘-‘) f=-1;
    for(;isdigit(c);c=Getchar()) x=x*10+c-‘0‘;
    return x*f;
}
#define S 1200000
char pf[S],*o1=pf,*o2=pf+S;
#define ot(x) (o1==o2?fwrite(pf,1,S,stdout),*(o1=pf)++=x:*o1++=x)
inline void print(ll x){static char s[20],*b;b=s;if(!x)*b++=48;for(;x;*b++=x%10+48,x/=10);for(;b--!=s;ot(*b));}
const int maxn=1000010;
int n,q;
ll B[maxn],ans[maxn];
int main() {
	n=read();q=read();
	rep(i,1,n) for(int j=i;j<=n;j+=i) B[j]++;
	while(q--) {
		int t=read(),x=read();
		if(t==2) print(ans[x]),ot(‘\n‘);
		else {
			int v=read();
			for(int i=x;i<=n;i+=x) ans[i]+=v*B[i/x];
		}
	}
	fwrite(pf,1,o1-pf,stdout);
	return 0;
}

C 平均数

明显的01分数规划,二分一下答案然后问题就转化成计算有多少连续子序列和>0,离散一下树状数组算一下就行了。

注意精度问题。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
using namespace std;
inline int read() {
    int x=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c==‘-‘) f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘;
    return x*f;
}
typedef long long ll;
const int maxn=100010;
const double eps=1e-12;
ll k;
int n,A[maxn],C[maxn];
int sumv[maxn];
void add(int x) {for(;x<=n+1;x+=x&-x) sumv[x]++;}
int sum(int x) {int res=0;for(;x;x-=x&-x) res+=sumv[x];return res;}
double B[maxn],tmp[maxn];
ll check(double x) {
	memset(sumv,0,sizeof(sumv));
	rep(i,1,n) B[i]=(A[i]-x)*1e10;
	rep(i,1,n) B[i]+=B[i-1];
	rep(i,1,n) tmp[i]=B[i];tmp[n+1]=0.0;
	sort(tmp+1,tmp+n+2);
	rep(i,1,n+1) if(fabs(tmp[i]-tmp[i-1])<eps) tmp[i]=tmp[i-1];
	rep(i,0,n) C[i]=lower_bound(tmp+1,tmp+n+2,B[i])-tmp;
	ll ans=0;
	rep(i,1,n) {
		add(C[i-1]);
		ans+=sum(C[i]);
	}
	return ans;
}
int main() {
	n=read();scanf("%lld",&k);
	double l=0.0,r=0.0;
	rep(i,1,n) r=max(r,(double)(A[i]=read()));
	while(r-l>1e-10) {
		double mid=(l+r)*0.5;
		if(check(mid)>=k) l=mid;
		else r=mid;
	}
	printf("%.6lf\n",l);
	return 0;
}

D 小Q的家庭作业

手(da)推(biao)公(da)式(fa)得g(n)=n*d(n),其中d(n)表示n的约数个数。

设n=∏(pi^ci),则d(n)=∏(ci+1)。

然后这个问题就简单了,因为数的范围是[1,10^7],暴力搞搞循环节,线性筛一下最小质因子就行了。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
using namespace std;
typedef long long ll;
inline ll read() {
    ll x=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c==‘-‘) f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘;
    return x*f;
}
const int maxn=10000010;
const int mod=1000000007;
int pow(ll n,ll m) {
	ll ans=1;
	for(;m;m>>=1,(n*=n)%=mod) if(m&1) (ans*=n)%=mod;
	return ans;
}
int pri[maxn/10],d[maxn],cnt;
bool vis[maxn];
void init(int n) {
	d[1]=1;
	rep(i,2,n) {
		if(!vis[i]) pri[++cnt]=i,d[i]=i;
		rep(j,1,cnt) {
			if(i*pri[j]>n) break;
			vis[i*pri[j]]=1;
			if(i%pri[j]==0) {d[i*pri[j]]=d[i];break;}
			d[i*pri[j]]=pri[j];
		}
	}
}
int x1,a,b,c,k,A[maxn];
ll m;
int main() {
	m=read();x1=read();a=read();b=read();c=read();
	init(c);A[x1]=1;int x=x1;
	ll ans=1;(ans*=x1)%=mod;
	do {
		k++;
		x=((ll)x*a+b)%c+1;A[x]++;(ans*=x)%=mod;
	}while(A[x]==1&&k<m-1);
	if(k<m-1) {
		A[x]--;(ans*=pow(x,mod-2))%=mod;
		while(x1!=x) k--,m--,x1=((ll)x1*a+b)%c+1;
		ll t=m/k,ct=1;m-=t*k;t--;
		do {
			(A[x]+=t%mod)%=mod;if(m) A[x]++,m--,(ans*=x)%=mod;
			(ct*=x)%=mod;
			x=((ll)x*a+b)%c+1;
		}while(x!=x1);
		(ans*=pow(ct,t))%=mod;
	}
	dwn(i,c,2) {
		if(d[i]==i) (ans*=A[i]+1)%=mod;
		else (A[i/d[i]]+=A[i])%=mod,(A[d[i]]+=A[i])%=mod;
	}
	printf("%lld\n",ans);
	return 0;
}

  

时间: 2024-08-07 00:12:46

51nod算法马拉松14的相关文章

51Nod 算法马拉松21(迎新年)

这次打算法马拉松是在星期五的晚上,发挥还算正常(废话,剩下的题都不会= =). 讲讲比赛经过吧. 8:00准时发题,拿到之后第一时间开始读. A配对,看上去像是二分图最大权匹配,一看范围吓傻了,先跳过读后面的题. B完全二叉树的方差,大概看了一遍,好神的样子,跳过. C多项式?好吧没学过FFT和NTT的我肯定不会,跳跳跳. D最大值,哎呦这函数什么破玩意儿,看不懂,跳跳跳. E B君的射击,卧槽毕克大人您出题就算了出这么一道码农题是要闹那样,跳跳跳. F那些年,我们一起讲的故事,卧槽这特么简直就

随便玩玩系列之一:SPOJ-RNG+51nod 算法马拉松17F+51nod 1034 骨牌覆盖v3

先说说前面的SPOJ-RNG吧,题意就是给n个数,x1,x2,...,xn 每次可以生成[-x1,x1]范围的浮点数,把n次这种操作生成的数之和加起来,为s,求s在[A,B]内的概率 连续形的概率,想象为一个n维长方体,有两个平面与这个几何图形相割,于是就变成了求面(体)积问题,一般要去重,n维区域系数:s^n/n!,至于区间问题,直接前缀之差搞定 然后就是悲催的算法马拉松17F题了...其实是道好题来的,只是出题人不知世界上还有这题,然后某大牛把思路理清后把答案直接搬了过来 经典的1*2骨牌覆

51Nod 算法马拉松15 记一次悲壮而又开心的骗分比赛

OwO 故事的起源大概是zcg前天发现51Nod晚上有场马拉松,然后他就很开心的过去打了 神奇的故事就开始了: 晚上的时候我当时貌似正在写线段树?然后看见zcg一脸激动告诉我第一题有九个点直接输出B就可以A.. 然后之后zcg以奇怪的二分方式发现了如何A掉第一题的第十个点(我记得貌似是什么第5000个数等于511? OwO 就这样没有任何思考含量全凭骗分黑科技过掉了第一题 OwO 然后zcg打开了第二题,发现第二题样例有点问题,然后就发了个帖子,直接去看第三题了 我去瞅了一眼,发现这不是gcd

51nod算法马拉松 contest7

A题 链接:http://www.51nod.com/contest/problem.html#!problemId=1417 推荐链接:http://blog.csdn.net/a837199685/article/details/45009337 设美女取得正面概率是p,反面就是(1-p),就是美女取一正一反和一反一正的概率相同,然后推出公式y=((a+b)/2+b)/(2*(a+b)); 1 #include<iostream> 2 #include<cstdio> 3 #i

51nod 平均数(马拉松14)

平均数 alpq654321 (命题人) 基准时间限制:4 秒 空间限制:131072 KB 分值: 80 LYK有一个长度为n的序列a. 他最近在研究平均数. 他甚至想知道所有区间的平均数,但是区间数目实在太多了. 为了方便起见,你只要告诉他所有区间(n*(n+1)/2个区间)中第k大的平均数就行了. Input 第一行两个数n,k(1<=n<=100000,1<=k<=n*(n+1)/2). 接下来一行n个数表示LYK的区间(1<=ai<=100000). Outp

51Nod 算法马拉松23 开黑记

惨啊--虽然开了半天黑,但是还是被dalao们踩了-- 第二次开黑,还是被卡在rank20了,我好菜啊--= = 写一写比赛经过吧-- 看到题之后习惯性都打开,A~D看上去似乎并没有什么思路,F应该是道数论题,看了E感觉有点意思,一看数据范围,咦怎么只有$50000$,再仔细看一看式子,手动分情况讨论之后得到一个结论-- 这题是水的线段树维护莫队啊= = 然后就开始码码码,由于一些脑残错误调了一会儿,然后就得到了这样的结果: 我坚信自己莫队的复杂度没错,然后就开始各种王逸松卡常,使用的卡常技巧包

51nod 算法马拉松4

http://www.51nod.com/contest/problemList.html#!contestId=9 D 装盒子 拓扑排序?

51NOD算法马拉松 最大值问题 离线预处理+set lower_bound

题目:http://www.51nod.com/contest/problem.html#!problemId=1349 题意:100000个数的序列,有100000次询问,每次问区间最大值大于等于k的区间有多少? 思路:一开始没看到"大于等于",想了很久也不会,原来看错题了.看错题害死人. 一般询问的问题,如果不能用线段树log(n)求出,那么就离线做. 首先将询问按从大到小排序,再将序列中的每个数排序,注意记录序号. 对于当前询问,每加进一个数,我需要找到它在加进的序列(按大小有序

51nod 算法马拉松4 D装盒子(网络流 / 二分图最优匹配)

装盒子 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 有n个长方形盒子,第i个长度为Li,宽度为Wi,我们需要把他们套放.注意一个盒子只可以套入长和宽分别不小于它的盒子,并且一个盒子里最多只能直接装入另外一个盒子 (但是可以不断嵌套),例如1 * 1 可以套入2 * 1,而2 * 1再套入2 * 2.套入之后盒子占地面积是最外面盒子的占地面积.给定N个盒子大小,求最终最小的总占地面积. Input 第一行一个数N表示盒子的个数. 接下来N行,每行两个正整数,表示每个盒子的长