1)应该是扩展欧几里得求逆元元.具体怎么回事,我是怎么也看不懂

2010年10月 C/C++大版内专家分月排行榜第二
2010年10月 C/C++大版内专家分月排行榜第二
2010年10月 C/C++大版内专家分月排行榜第二
本帖子已过去太久远了,不再提供回复功能。09-1509-0809-0509-06
02-0201-2201-1004-07
◇本站云标签> 问题详情
设环R是环R1,R2….Rn的直和,即 设R是一个有单位元(用1表示)的环,a,b∈R.证明:如果1+ab在R中有逆元
悬赏:0&答案豆
提问人:匿名网友
发布时间:
设R是一个有单位元(用1表示)的环,a,b∈R.证明:如果1+ab在R中有逆元,则1+ba在R中也有逆元.请帮忙给出正确答案和分析,谢谢!
我有更好的答案
相关考试课程
请先输入下方的验证码查看最佳答案
图形验证:
验证码提交中……
享三项特权
享三项特权
享三项特权
选择支付方式:
支付宝付款
郑重提醒:支付后,系统自动为您完成注册
请使用微信扫码支付(元)
支付后,系统自动为您完成注册
遇到问题请联系在线客服QQ:
请您不要关闭此页面,支付完成后点击支付完成按钮
遇到问题请联系在线客服QQ:
恭喜您!升级VIP会员成功
常用邮箱:
用于找回密码
确认密码:‘ACM’ 分类的存档
看Game Theory的时候看到的这个题目:
一共有N堆石子,每堆石子的数目告诉你,然后两个人轮流从中取石子,每次最多从K堆中取,每堆取的石子数任意,每次最少取一颗石子.假设两个人都足够聪明的话,最后没石子可取的人算输,问先手和后手谁输谁赢.
以前看到这个题目的时候只是按照提示证了一下,知道这个是正确的,但是如果不知道结果的话,可能就不知道怎么想了.后来给别人讲这题的时候,突然想起其实这个题就是两个简单的博弈题的结合:报数问题,和简单的取石子游戏问题.
首先我们知道报数问题是给一个数N,每个人每次最多报K个数,最少报1个数,先报道N的算赢,问谁会赢.这个大家都会了,就是算N%(K+1)的结果就行了.
简单的取石子游戏就是上面的取石子游戏中K=1.也就是每次只能从1堆中取石子.这个题目大家也知道了,就是把所有的石子数目抑或起来,看结果是否为0.其实抑或就是先化成2进制,然后看相应的为加起来是否能整除2.
OK,那么如果我们每次最多取K堆石子的话,也就是说两个人每次都可以改变K+1堆石子(就像报数中两个人每次都可以报K+1个数)这样的话,我们就只要把N堆石子的数目化成2进制之后,然后对每一位都加起来,看是否整除K+1就行了.
福州赛区的A题,我们队因为没有过这个题导致最后的悲剧,废话不多说了,下面是简单的分析+代码.
首先我们可以设置一个map[][]数组记录某个点有没有子,然后让将做四个方向,再判断是否会被吃掉,如果有一个方向不会被吃掉,那么就不是死棋,否则就是。
判断是否会被吃掉的时候,如果是帅,就判断y坐标相等,且中间无子,车的判断类似。炮的判断可以变为炮和将中间有几个子,一个的话就ok,否则炮吃不了将。马的话,考虑不能走就行了。
#include &cstdio&
#include &cstring&
#include &cstdlib&
#include &cmath&
char role[30];
int x[30],y[30];
int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int hdir[8][2]={{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1},{-2,1}};
bool have[30][30];
int min(int a,int b)
return a&b?a:b;
int max(int a,int b)
return a&b?a:b;
bool can(int X,int Y)
for(i=0;i&n;++i)
if(!have[x[i]][y[i]])
if('G'==role[i])
if(y[i]==Y)
for(j=min(X,x[i])+1;j&max(X,x[i]);++j)
if(have[j][Y])
if(j==max(X,x[i]))
return false;
if('R'==role[i])
if(Y==y[i])
for(j=min(X,x[i])+1;j&max(X,x[i]);++j)
if(have[j][Y])
if(j==max(X,x[i]))
return false;
if(X==x[i])
for(j=min(Y,y[i])+1;j&max(Y,y[i]);++j)
if(have[X][j])
if(j==max(Y,y[i]))
return false;
if('C'==role[i])
if(X==x[i])
for(j=min(Y,y[i])+1;j&max(Y,y[i]);++j)
if(have[X][j])
if(1==cnt)
return false;
if(Y==y[i])
for(j=min(X,x[i])+1;j&max(X,x[i]);++j)
if(have[j][Y])
if(1==cnt)
return false;
if('H'==role[i])
for(j=0;j&8;++j)
tx = x[i]+hdir[j][0];
ty = y[i]+hdir[j][1];
if(tx&1||tx&10||ty&1||ty&9)
sbx = x[i]+hdir[j][0]/2;
sby = y[i]+hdir[j][1]/2;
if(have[sbx][sby])
if(tx==X&&ty==Y)
return false;
return true;
int main(void)
#ifndef ONLINE_JUDGE
freopen("1001.in","r",stdin);
freopen("1001.out","w",stdout);
while(EOF!=scanf("%d%d%d",&n,&X,&Y))
if(0==n&&0==X&&0==Y)
memset(have,false,sizeof(have));
for(i=0;i&n;++i)
ch=getchar();
while(!(ch&='A'&&ch&='Z'))
ch=getchar();
scanf("%d%d",&x[i],&y[i]);
have[x[i]][y[i]]=true;
for(i=0;i&4;++i)
tx = X+dir[i][0];
ty = Y+dir[i][1];
if(tx&1||tx&3||ty&4||ty&6)
tmp = have[tx][ty];
have[tx][ty]=false;
if(can(tx,ty))
have[tx][ty]=
printf("YES\n");
printf("NO\n");
今天终于把第5章搞定了.USACO还剩下3题,早日结束了这3题,任务还很艰巨啊.
简单写下这两节的题解.这两节搞了好久啊.有些题还是看了题解之后,然后差不多是照着标称打的(- -|).
ALL Latin:比较变态的一道搜索题,7的时候过不去,然后看的题解,那个循环群什么的不是很懂,用的是另外一种方法,就是首先第一行第一列都放好(最后结果再乘以(n-1)!就行),然后第2行第2列放2,3,4,5的方案是一样多的.貌似比较慢,最慢的0.9+s
Canada Tour:费用流的方法没弄,用的是DP,类似方格取数的那种多线程DP,只需要看最后是不是有两条独立的路径从起点到终点就OK了,中间不能有重复的点
Character Recognition:很烦的一道题,借鉴标称的,方法:DP,有一点就是多余的那一行的变化数不算在里面的.然后如果知道了前i行的可以推知i+19,i+20,i+21的情况.
Betsy's Tour:正解是连通性DP?czw和我说了下这是最简单的连通性DP,但是那论文看不懂,刚好这题可以搜过,只需要考虑下,如果进入了死胡同就不要搜了,还有如果当前的路径把格子分成了两边就不用搜了.死胡同那个可以考虑做过这个点之后,它的上下左右点是否被走过,一个点必须有进有出才行(不然进死胡同了),除了起点和终点
TeleCowmunication:拆点,最大流,然后枚举删点.拆点时,每个点拆成2*i,2*i+1,然后流量是1,原边中有边的则加两条无穷大的边,跑最大流,然后枚举删点.看删掉点之后是不是最大流减少了.是的话就输出这个点,最大流减少,继续枚举
Picture:很早以前就听说这题是线段树的好题,但是我还是用了朴素的方法(小汗一下),直接把横向边和纵向边分别排序,然后遇到起始边(坐标小的)就+1.否则-1.这样如果由0-&1,那么一定是最终矩形的边,这样枚举完了之后,在USACO还挺快.线段树就是在更新+1,-1的时候用线段树,可以做到区间处理.降低时间复杂度
Hidden Passwords:刚好czw和我说过最小表示法,然后就直接做了.或许这是这两节我觉得最简单的了- -|.貌似还有很多其他方法,可以看看nocow的分析
Two Five:就是一个一个算就行了.主要是要好写,而且速度还过得去.对于数变字符串.可以枚举25个位置,如果某个位置放字符ch的数目加上前面算的结果已经超过了给的n,那么就把这个位置放置ch,因为放置ch-1的时候不够,然后接着放下一个位置,直到25个位置全放好为止,字符串变数字的差不多,只不过把上面的操作反过来而已,就是看这个字符之前有多少个.比如求ACD的,那么我们就求ABC,ABD,ACB,的方案数,然后再求ACD后面有多少个,就像求10进制数的大小一样,求521是第几个,可以首先求1**,2**,3**,4**的个数,然后求5*_(*&2)和52*(*&1)的个数,最后结果+1就是521的结果了
接下来还有三题,搞定也算是圆满了USACO,加油吧
题目大致意思就是:求1,2,3.....N有多少个排列是用冒泡排序只需要k轮就好的.给定一个n和一个k,然后让你输出答案模上一个数.因为答案是在太大了
这里首先给出公式吧对给定的n和k,答案是k!*((k+1)^(n-k)-k^(n-k)).
ps:以下分析借助了&计算机程序设计艺术&和
首先我们知道对于每个排列和其逆序对是一一对应的.也就是说一个逆序对对应一个排列,一个排列对应一个逆序对,相同排列的逆序是一样的,同一个逆序对的排列也是一样的.下面我们来看看这个和逆序对有啥关系.这里以4 5 3 1 2这个排列为例.那么逆序对为3 3 2 0 0.也就是1的逆序数为3,2的为3,依次下去.那么我们来看下依次冒泡排序会改变什么,首先第一趟我们会发现变成了4 3 1 2 5.那么逆序对变成了2 2 1 0 0也就是所有逆序数&0的都-1了,这个是偶然吗?不是的,因为对于每一趟冒泡,都有一个当前未排好序的最大的沉到最下面去,这样就会导致这个当前最大的数的后面的那些数的逆序数都会-1.上面的当前最大就是5,5后面的是3 1 2,所以3 1 2这几个数的逆序数都会-1.OK,现在我们知道,对于每趟冒泡排序,所有逆序数不为1的都会-1,那么体重要求的我们可以转化成求这样的排列的个数:也就是逆序数的最大值为k的n个数的一个排列.这样我们就得到了一个冒泡最多需要k次的一个排列,而且逆序数和排列是一一对应的,所以我们得到的"逆序数的最大值为k的n个数的排列"的个数就是本题的答案.
现在的问题变成了求逆序数的最大值为k的n个数的排列的个数,也就是给你n个位置,这n个位置上可以放置一系列数,但是最大为k,最小0的排列的数目,而且我们这里要求的是至少要有一个数=k(不然不需要k趟就排完了).那么我们可以考虑用最大的为k减去最大的为k-1的排列,剩下的就是至少有一个最大值为k的了.现在我们求最大值为k,但不一定有最大值为k的排列的数目.我们可以这么想:对于1,有逆序数为0,1.....k这些选择,也就是它的位置可以选择为0 1 2...k(位置从0开始),放置好1之后,我们再放2,同理可以得到一系列的位置,也就是2也可以有k+1中选择,知道某个数不可能出现逆序数为k为止,那么我们知道一个数的最大逆序数位n-i(i是这个数,这里的环境都是1,2....n这样的排列).那么最大的i就是k了.所以这里有(k+1)^(n-k),然后剩下的就自己选位置吧,有k!种方案,所以就是k!((k+1)^(n-k)).那么我们的结果就是k!*(k+1)^(n-k)-(k-1)!*k^(n-k+1)然后化简就变成了k!((k+1)^(n-k)-k^(n-k))到这里这题也结束了,不过还有一点,在保证不会越界的情况下,能不用mutil_mod(算a*b%c),这类的函数就不用,所有函数都是有开销的,别到时TLE了还找不到原因
半平面交,一开始以为很神奇的东西,看zzy的论文,看了好久,发现思路还好懂,不会写代码= =,只是觉得和melkman有点像.后来网上膜拜了各位牛人的代码,自己终于写出来了,A了2451,不过的时候发现了自己代码的错误,如果有多条直线平行那么我的代码会错,后来又在3335发现如果有反向平行且不共线的两条直线那么我的会错.于是各种改过之后,觉得现在的代码应该没啥问题了= =||
主要思路就是先对边进行排序[按极角序],然后去重,把平行同向的直线只保留规约最紧的一条.然后对留下来的进行半平面交.现在觉得单独的半平面交不难,难的是把题目转化为半平面交
2451代码如下[如有错误还请指出]
#include &stdio.h&
#include &string.h&
#include &stdlib.h&
#include &math.h&
#include &algorithm&
typedef struct
double x,y;
typedef struct
TPoint p1,p2;
typedef struct
double a,b,c;
const int maxnum=20016;
const double eps=1e-8;
TPoint pg[maxnum];
TLine line[maxnum],dq[maxnum+2];
void Add_line(int idx,double x1,double y1,double x2,double y2)
line[idx].p1.x = x1;
line[idx].p1.y = y1;
line[idx].p2.x = x2;
line[idx].p2.y = y2;
line[idx].angle = atan2(y2-y1,x2-x1);
void input()
double x1,y1,x2,y2;
for(i=0;i&n;i++)
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
Add_line(i,x1,y1,x2,y2);
Add_line(n,0,0,10000,0);
Add_line(n+1,10000,0,10000,10000);
Add_line(n+2,10000,10000,0,10000);
Add_line(n+3,0,10000,0,0);
int dou2int(double x)
if(x&-eps)
return -1;
double cross(TPoint a,TPoint b,TPoint c)
return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
bool cmp(TLine l1,TLine l2)
int ret = dou2int(l1.angle-l2.angle);
if(ret & 0)
return true;
if(ret & 0)
return false;
if(dou2int(cross(l2.p1,l2.p2,l1.p2))&0)
return false;
return true;
abcLine Get_line(TPoint p1,TPoint p2)
ret.a = p1.y-p2.y;
ret.b = p2.x-p1.x;
ret.c = p1.x*p2.y-p2.x*p1.y;
TPoint Get_jiao(TLine l1,TLine l2)
abcLine A,B;
A = Get_line(l1.p1,l1.p2);
B = Get_line(l2.p1,l2.p2);
ret.x = (B.b*A.c-A.b*B.c)/(B.a*A.b-A.a*B.b);
ret.y = (A.a*B.c-B.a*A.c)/(B.a*A.b-A.a*B.b);
bool check(TLine l1,TLine l2,TLine l3)
TPoint cro = Get_jiao(l1,l2);
if(dou2int(cross(l3.p1,l3.p2,cro))&0)
return false;
return true;
bool overline(TLine l1,TLine l2)
int a,b,c,d;
a = (l1.p1.y-l1.p2.y)*(l2.p1.x-l2.p2.x);
b = (l1.p1.x-l1.p2.x)*(l2.p1.y-l2.p2.y);
c = l1.p1.x-l1.p2.x;
d = l2.p1.x-l2.p2.x;
ret = dou2int(cross(l1.p1,l1.p2,l2.p1));
if((a==b) && (c*d&0) && (0 != ret))
return true;
return false;
void work()
sort(line,line+n,cmp);
for(int i=1;i&n;i++)
if(dou2int(line[i].angle-line[i-1].angle)==0)
memmove(line+i-1,line+i,(n-i)*sizeof(line[0]));
dq[bot]=line[0];
dq[top]=line[1];
for(int i=2;i&n;i++)
while(top&bot && check(dq[top-1],dq[top],line[i]))
while(top&bot && check(dq[bot+1],dq[bot],line[i]))
dq[++top]=line[i];
while(top&bot && check(dq[top-1],dq[top],dq[bot]))
while(top&bot && check(dq[bot+1],dq[bot],dq[top]))
dq[--bot]=dq[top];
if(top-bot&3)
printf("0.0\n");
for(int i=i&i++)
pg[idx++] = Get_jiao(dq[i],dq[i+1]);
double ans=pg[idx].x*pg[0].y-pg[0].x*pg[idx].y;
for(int i=0;i&i++)
ans += pg[i].x*pg[i+1].y-pg[i+1].x*pg[i].y;
ans /= 2.0;
if(ans & 0)
printf("%.1f\n",ans);
int main(void)
#ifndef ONLINE_JUDGE
freopen("2451.in","r",stdin);
freopen("2451.out","w",stdout);
scanf("%d",&n);
这题一开始以为很难,然后直接pass了,后来看到有人写解题报告才70+行的代码,于是决定写这题-_-||||.写到一半无奈那位朋友的方法不懂,好吧那自己慢慢搞吧[那位朋友貌似用复数搞的,无限ym啊]然后搞了好久一直处于样例不过的状态,而且网上解题报告很少.一直查思路,查代码.一直觉得自己思路是对的[自己当然觉得自己是对的了-_-||],后来幸运搞到几组数据,然后各种改啊,就过了,下面是思路:
首先可以把打圆平移到和原点重合,然后大圆半径减去小圆半径.再处理其他的.然后小圆变成一个点
1.算出小圆和和大圆第一碰撞所需时间,如果所给时间比这个时间短,直接算,否则进入2
2.算出第一次碰撞的交点,和相应的夹角,假设圆心为0,小圆起始点为A,碰撞点为B,第二次碰撞的交点为C,算出角ABO的大小,然后可以算出BC的长度和所需要的时间,这样就可以了
3.得到上面的信息之后,可以算出经过整数次弦长之后,还剩下多少时间,以及所处的位置和当前的速度方向,然后剩下的就简单了.最后再把大圆的圆心反原回去即可
要注意的是旋转的时候一定要考虑到底是顺时针还是逆时针,我就是因为这个WA了n次!!!
#include &stdio.h&
#include &string.h&
#include &stdlib.h&
#include &math.h&
const double eps = 1e-6;
const double pi = acos(-1.0);
typedef struct
double x,y;
typedef struct
double x,y,r;
TCircle ball,
TPoint vec,
inline double squ(double x)
return x*x;
double dot(TPoint a,TPoint b,TPoint c)
return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y);
int cross(TPoint a,TPoint b,TPoint c)
double ret = (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
if(ret&eps)
return -1;
void work()
convert.x = ball.x;
convert.y = ball.y;
sball.x -= convert.x;
sball.y -= convert.y;
ball.x =0;
ball.y = 0;
ball.r -= sball.r;
TPoint me = {sball.x,sball.y};
if(fabs(vec.x) & eps && fabs(vec.y) & eps)
me.x += convert.x;
me.y += convert.y;
printf("%.1f %.1f\n",me.x,me.y);
if(fabs(ball.r)&eps)
me.x += convert.x;
me.y += convert.y;
printf("%.1f %.1f\n",me.x,me.y);
if(squ(me.x+T*vec.x)+squ(me.y+T*vec.y)+eps&squ(ball.r))
me.x = me.x+T*vec.x;
me.y = me.y+T*vec.y;
me.x += convert.x;
me.y += convert.y;
printf("%.1f %.1f\n",me.x,me.y);
double k=vec.y/vec.x;
double b=me.y-k*me.x;
double x1;
if(vec.x&0)
x1=(-k*b-sqrt(squ(k*ball.r)+squ(ball.r)-squ(b)))/(squ(k)+1);
x1=(-k*b+sqrt(squ(k*ball.r)+squ(ball.r)-squ(b)))/(squ(k)+1.0);
double y1=k*x1+b;
TPoint tmp1 = {x1,y1};
TPoint tmp2 = {0,0};
double u = dot(tmp1,tmp2,me);
flag = cross(tmp1,tmp2,me);
u = u/(sqrt(squ(x1-me.x)+squ(y1-me.y))*ball.r);
double l=(u)*ball.r;
u = acos(u);
double t1 = l/sqrt(squ(vec.x)+squ(vec.y));
__int64 time = (T-(x1-me.x)/vec.x)/t1;
T = T-(x1-me.x)/vec.x-time*t1;
double u2=atan2(y1,x1);
double u3 = (time+1)*(pi-2*u)*
u2 += time*(pi-2*u)*
double x2 = ball.r*cos(u2);
double y2 = ball.r*sin(u2);
TPoint vec2;
vec2.x = vec.x*cos(u3)-vec.y*sin(u3);
vec2.y = vec.x*sin(u3)+vec.y*cos(u3);
me.x = x2+vec2.x*T+convert.x;
me.y = y2+vec2.y*T+convert.y;
printf("%.1f %.1f\n",me.x,me.y);
int main(void)
#ifndef ONLINE_JUDGE
freopen("G.in","r",stdin);
freopen("G.out","w",stdout);
scanf("%d",&t);
while(t--)
scanf("%lf%lf%lf",&ball.x,&ball.y,&ball.r);
scanf("%lf%lf%lf",&sball.x,&sball.y,&sball.r);
scanf("%lf%lf%lf",&vec.x,&vec.y,&T);
这题可以用线段树直接做,保存的节点信息是所有的乘积[模上之后的],不过线段树不好敲,如果有模板的话,还好.没有模板的话,那么少则30分钟吧.
后来才发现原来可以用树状数组+逆元解决这个问题,当然用树状数组和逆元的话,就需要知道两个问题:
1.乘法符合区间可加性
2.a/b%p &====& c*a%p 其中c是b的逆元
这题就是用了这两条性质,这两条性质想清楚之后,这题就好敲了,当然树状数组的更新和求值就会有一点小小的变化.首先对于每个求区间的乘积的问题.我们可以转化成(get(k2)*c)%p[get是树状数组的求值函数,(c*get(k1-1))%p=1,也就是c是get(k1-1)的逆元]更新也用到逆元,所以增加一个数组来存每个元素.附代码:
#include &stdio.h&
#include &string.h&
#include &stdlib.h&
#include &math.h&
const int max=50006;
const __int64 mod=;
__int64 tree[max];
__int64 num[max];
void init_tree()
for(int i=0;i&i++)
tree[i]=1;
void update(int idx,__int64 val)
while(idx&=max)
tree[idx] = (tree[idx]*(val%mod))%
idx += idx & -
__int64 get(int idx)
__int64 ret=1;
while(idx&0)
ret = (tree[idx]*ret)%
idx -= idx & -
return ret%
void ex_gcd(__int64 a,__int64 b,__int64 &x,__int64 &y)
if(0 == b)
ex_gcd(b,a%b,x,y);
y = t - a/b*y;
int main(void)
freopen("3074.in","r",stdin);
freopen("3074.out","w",stdout);
__int64 k1,k2;
__int64 x,y;
__int64 a,b;
scanf("%d",&t);
while(t--)
init_tree();
scanf("%d",&n);
for(int i=1;i&=n;i++)
scanf("%d",&tmp);
update(i,tmp);
for(int i=1;i&=n;i++)
printf("%I64d
%I64d\n",num[i],tree[i]);
scanf("%d",&q);
while(q--)
scanf("%d%I64d%I64d",&type,&k1,&k2);
if(1==type)
ex_gcd(num[k1],mod,x,y);
x = (x%mod+mod)%
update(k1,x);
update(k1,k2);
num[k1]=k2;
printf(":::x:::%d\n",x);
a=get(k2);
b=get(k1-1);
ex_gcd(b,mod,x,y);
x = (x%mod+mod)%
a = ((a%mod)*(x%mod))%
printf("%I64d\n",a);
printf("=============\n");
for(int i=1;i&=n;i++)
printf("%I64d
%I64d\n",num[i],tree[i]);
我们队的第二次正式比赛,下一次正式比赛应该就是省赛了.
[由于29号早上3点左右有欧冠决赛,所以我被吵醒了好几次,从3点到5点一直没睡着.]
下面是比赛记录.基本纯流水账.
首先是A F J,由于我们一开始开题不对(A),加上写A的不是对计算几何不是特别熟悉,所以我们的A是53'时过的,但是中间,知道J更容易,确没有及时的抢过机器来写.A是1A,然后是J,悲剧的是J不知为何TLE了,怎么想都不可能的事情啊.TLE两次之后就换人写了.3A.[J换人写一共浪费了两个人40'左右,加上罚时40',也就是说J一共浪费了80'左右的时间],然后20分钟后,F 1A.还以为接下来就是我们的show time了,结果就悲剧了,一个G(gcd_depth),一个D(dp),一个H(找规律/组合)D由于认为不可能出成恶心的高精度,认为转移方程错了,放弃.H和G就不知道是为啥错了,后面3小时一直在调这两个题(赛后问了下裁判,思路基本是对的,看来又tm是实现问题).还有就是E居然就是一个裸的离散对数,而且a^x=b(mod c),c还是个素数,我去啊.不过这些都是后话了,比赛已经过去了.反正就是被各种踩,我们是各种送,送成狗了.
下面说点关于我的,其实J我也想早早的抢过机器来写,可是我又怕不1A,又怕耽误时间,反正就是各种怕,然后就只能干等着,关于J的两次TLE,我也不知道是怎么了,应该是我的程序风格的问题,但是队友检查时也没看出什么可以TLE的东西,可是tm的重写就过了,关于后面的E,在还有90'左右的时候,我看过榜之后,还是看了下E的,只是没有自己分析,不过心里知道,肯定是个裸的数论题,但是由于G的Wa,和其他一系列原因,就"忘"了E,只有在讲解题报告时才想起还有一道裸的离散对数,这tm和不知道离散对数不是一样的结果么.我觉得我最大的问题不是知识的不足,而是信心的不足,不知道从什么时候开始,已经没有了那种舍我其谁的霸气了,已经被完全钝化了,接下来的几个月,首要任务是找回那种霸气,其次才是弥补知识的不足.
昨天,今天虐我的,明天我会虐回来的
===本来是去湖大校赛的,后来由于某些原因,我们就去了湘潭(当然我更倾向于去湘潭)===
我们队应该说还是不成熟,个人(我)能力不行,团队配合不是很好,有时另外两个人根本听不懂剩下的那个人在说什么(或者说根本没在听),代码能力还有待加强.1A率不高.下面是流水账,按出题顺序来写.(由于湘潭周二还会挂网络赛,所以就不说算法了,等网络赛完了之后再补吧)
A,水题,然后写了交上去,由于没加stdio ce了,FB没了.
F, 3A(4A?)
E,两个人理解错题意,一开始想着随机水(因为过的人已经不少了),后来Azuki看题后,才发现其他两个人看错题了,囧啊.让后Gamor敲之,这期间其他两个人在邪恶的吃着中餐(香喷喷的鸡腿-_-||),这题由于一些细节问题TLE了一次,2A.
接下来就成了垃圾时间了,其实这个时候,我们还是有优势的,不过后面差不多两个小时就没有一点作为,首先是Azuki的H,一直WA,然后三人一直搞这个,思路怎么想都没问题,数据也测了好多,居然没测出问题.然后这题最后也没过,赛后谢大说只错了小数据(他们还手算了我们出错的数据,太谢谢了),这个应该是实现问题了.还有一个G,由于H和G题题意不是很清楚的缘故,没敢上去写,其实给半个小时,G题应该没啥问题.然后郭嘉三国杀那题,确实没想到算法,最后一题Azuki说他会做,还有主要程序段的模板,可是他没看题,然后其他两个看过题的不懂算法= =||。然后就悲剧的收场了.然后没有拿到monsterkill
比赛结束后我去湘大逛了一圈,不过时间太紧了,然后就回科大了,结果在科大还等了好久-_-||,然后就回来了,这次湘大之行郁闷的占6/10,高兴的占4/10吧,郁闷的是被再踩(这个还好),没有monsterkill.
解题报告上给的是:
AC自动机/Trie图
首先给出,He函数是一个积性函数,然后He[p^n]=2,其中p是素数.那么He[n]就是2^k,k是不同素数的个数.那么HeHe[n]函数就是计算所有的n/p,p是素数.那么这题就变成了证明He[n]是素数函数.下面给出一个简单证明,如有错误还请指出:
首先He[p]=2.p是素数.
x^2=x(mod p)----&p|x(x-1).因为x&p所以p不整除x也不整除x-1.所以成立的情况下是x=1或者x=0.
He[p^k]=2,证明类似上面的
对于不同的两个素数p和q,He[p*q]=4=He[p]*He[q];
首先x=0和x=1是肯定成立的,
现在由x^2=x(mod p*q)
---&p*q|x(x-1)
假设x=k*p[k&q]
------&p*q|k*p(k*p-1)
-------&q|k(k*p-1)
-------&q|(k*p-1)
q是素数 所以gcd(k,q)=1
-------&k*p+t*q=1
这里就变成了这个方程的解,由扩展欧几里得知,这个方程有解,但是k在[0,q-1]之内的解就一个,所以这里多一个解,同理设x=k*p又有一个解,所以x^2=x(mod p*q)有4个解(x=0 ,x=1 ,x=k*p, x=k*q)
----&He[p*q]=4=He[p]*He[q];
那么He[p1^r1*p2^r2*……*pk^rk]=2^k然后可以进一步算出HeHe只需要算n以内每个素数的倍数的个数.
Random Posts已有人次读过此书...
已写49066字...
目前仍在拼命写作中...
最新免费章节:
本周红包排名
红包最新动态
粉丝荣誉榜
个性化周会员点击榜
一日江火精
楠权北腿精
一日江火精
楠权北腿精
一日江火精
楠权北腿精
女生周会员点击榜
云深无迹精
神宵蔽光精
云深无迹精
神宵蔽光精
云深无迹精
神宵蔽光精
Copyright (C)
All Rights Reserved 中文在线版权所有,
等在线小说阅读网站,未经许可不得擅自转载本站内容。
 京ICP备号-5 
 北京市公安局备案号码:1217k小说网所收录
作品、社区话题、
评论、用户上传文字、图片等其他一切内容及17k
网所做之广告均属用户个人行为,与17k}

我要回帖

更多关于 求逆元 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信