简短题解集合
有一些题比较水没什么新意,就懒得写长题解了
忘了日期的
BZOJ 1096 [ZJOI2007]仓库建设 (斜率优化DP)
先展开式子,移项,发现$x$递增,斜率$k$也是递增,用队列维护个下凸包就行了

1 #include <cmath> 2 #include <queue> 3 #include <vector> 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 #define N1 1010000 8 #define N2 4201 9 #define M1 120 10 #define ll long long 11 #define dd double 12 #define uint unsigned int 13 #define idx(X) (X-'0') 14 using namespace std; 15 16 ll gll() 17 { 18 ll ret=0;int fh=1;char c=getchar(); 19 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 20 while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();} 21 return ret*fh; 22 } 23 int n; 24 ll D[N1],p[N1],c[N1],f[N1]; 25 ll x[N1],y[N1]; 26 ll sp[N1],sdp[N1]; 27 int que[N1]; 28 29 int main() 30 { 31 //freopen("t2.in","r",stdin); 32 scanf("%d",&n); 33 for(int i=1;i<=n;i++) 34 { 35 D[i]=gll(),p[i]=gll(),c[i]=gll(); 36 sp[i]=sp[i-1]+p[i]; 37 sdp[i]=sdp[i-1]+1ll*p[i]*D[i]; 38 } 39 int hd=1,tl=0,j; 40 que[++tl]=0; 41 for(int i=1;i<=n;i++) 42 { 43 while(hd+1<=tl&&(y[que[hd+1]]-y[que[hd]])<=(x[que[hd+1]]-x[que[hd]])*D[i]) 44 hd++; 45 j=que[hd]; 46 f[i]=f[j]+ D[i]*sp[i]-D[i]*sp[j] -sdp[i]+sdp[j] +c[i]; 47 x[i]=sp[i],y[i]=f[i]+sdp[i]; 48 while(hd+1<=tl&&(y[que[tl]]-y[que[tl-1]])*(x[i]-x[que[tl-1]])>=(y[i]-y[que[tl-1]])*(x[que[tl]]-x[que[tl-1]])) 49 tl--; 50 que[++tl]=i; 51 } 52 printf("%lld\n",f[n]); 53 return 0; 54 }
BZOJ 4172 弹珠 (splay并不维护凸包优化DP)
插入,删除的操作用$splay$维护
$x$单调,斜率$k$不单调,用单调栈维护上凸包,每次把斜率在凸包上二分就行了

1 #include <cmath> 2 #include <queue> 3 #include <vector> 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 #define N1 501000 8 #define M1 205 9 #define ll long long 10 #define dd double 11 #define uint unsigned int 12 #define inf 233333333 13 using namespace std; 14 15 void gchar(char *str){ 16 char c=getchar();int cnt=0; 17 while(!((c>='A'&&c<='Z')||(c>='a'&&c<='z'))){c=getchar();} 18 while((c>='A'&&c<='Z')||(c>='a'&&c<='z')){str[++cnt]=c,c=getchar();} 19 str[++cnt]='\n'; 20 } 21 int gint() 22 { 23 int ret=0;int fh=1;char c=getchar(); 24 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 25 while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();} 26 return ret*fh; 27 } 28 int n,m,tp; 29 struct Splay{ 30 #define root ch[0][1] 31 #define il inline 32 int ch[N1][2],sum[N1],val[N1],fa[N1],tot; 33 il int idf(int x){return ch[fa[x]][0]==x?0:1;} 34 il void pushup(int x){sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+1;} 35 int cre(int w,int ff){tot++;sum[tot]=1,val[tot]=w,fa[tot]=ff;return tot;} 36 il void rot(int x) 37 { 38 int y=fa[x],ff=fa[y],px=idf(x),py=idf(y); 39 ch[y][px]=ch[x][px^1],fa[ch[x][px^1]]=y; 40 ch[x][px^1]=y,fa[y]=x,ch[ff][py]=x,fa[x]=ff; 41 pushup(y),pushup(x); 42 } 43 void splay(int x,int to) 44 { 45 to=fa[to];int y; 46 while(fa[x]!=to){ 47 y=fa[x]; 48 if(fa[y]==to) rot(x); 49 else if(idf(x)==idf(y)) rot(y),rot(x); 50 else rot(x),rot(x); 51 } 52 } 53 int srank(int K) 54 { 55 int x=root,p; 56 while(x) 57 { 58 if(sum[ch[x][0]]<K){ 59 K-=sum[ch[x][0]]; 60 if(K==1) return x; 61 K--,x=ch[x][1]; 62 }else{ 63 x=ch[x][0]; 64 } 65 }return 0; 66 } 67 int change(int p,int w) 68 { 69 int x=srank(p); 70 val[x]=w; 71 } 72 void insert(int p,int w) 73 { 74 if(tot==0){ 75 ch[0][1]=cre(w,0); 76 }else if(p==0){ 77 int x=srank(1);splay(x,root); 78 ch[x][0]=cre(w,x),pushup(x); 79 }else{ 80 int x=srank(p),y; 81 splay(x,root);y=ch[x][1]; 82 if(!y) ch[x][1]=cre(w,x),pushup(x); 83 else{ 84 while(ch[y][0]) y=ch[y][0]; 85 ch[y][0]=cre(w,y);pushup(y); 86 splay(y,root); 87 } 88 } 89 } 90 void reduct(int *a,int x,int &cnt) 91 { 92 if(ch[x][0]) 93 reduct(a,ch[x][0],cnt); 94 a[++cnt]=val[x]; 95 if(ch[x][1]) 96 reduct(a,ch[x][1],cnt); 97 } 98 #undef root 99 #undef il 100 }s; 101 int a[N1]; 102 int stk[N1],p[N1],q[N1]; 103 ll X[N1],Y[N1]; 104 105 int main() 106 { 107 //freopen("t2.in","r",stdin); 108 freopen("1.in","r",stdin); 109 freopen("a.out","w",stdout); 110 scanf("%d%d",&n,&m); 111 char str[10];int x,y; 112 for(int i=1;i<=m;i++){ 113 gchar(str); 114 if(str[1]=='I'){ 115 x=gint(),y=gint(); 116 s.insert(x,y); 117 }else{ 118 x=gint(),y=gint(); 119 s.change(x+1,y); 120 } 121 }n=0; 122 s.reduct(a,s.ch[0][1],n); 123 for(int i=1;i<=n;i++) 124 p[i]=gint(),q[i]=gint(); 125 stk[++tp]=0,X[0]=p[1],Y[0]=-inf; 126 stk[++tp]=1,X[1]=p[1],Y[1]=q[1]; 127 ll ans=0; 128 for(int i=2;i<=n;i++){ 129 int l=2,r=tp,pos=tp,mid; 130 while(l<=r){ 131 mid=(l+r)>>1; 132 if(Y[stk[mid]]-Y[stk[mid-1]]>=1ll*(X[stk[mid]]-X[stk[mid-1]])*a[i]) 133 pos=mid,l=mid+1; 134 else r=mid-1; 135 }int j=stk[pos]; 136 ans=max(Y[j]-1ll*X[j]*a[i],0ll); 137 printf("%lld\n",ans); 138 X[i]=p[i],Y[i]=q[i]; 139 while(tp>1&&1ll*(Y[stk[tp]]-Y[stk[tp-1]])*(X[i]-X[stk[tp-1]])<=1ll*(Y[i]-Y[stk[tp-1]])*(X[stk[tp]]-X[stk[tp-1]])) 140 tp--; 141 stk[++tp]=i; 142 } 143 return 0; 144 }
HDU 1693 / 洛谷 5074 (插头DP)
插头DP裸题,这道题只不过是可以用多条回路覆盖罢了
稍微修改一下判定条件,成一对的左括号右括号可以在任何位置合并
最小表示法写这道题比较麻烦,而且跑得比四进制慢
但我还是写了最小表示法
如果整个图都是0没有1,也算一种合法方案!

1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define N1 15 6 #define M1 50010 7 #define ll long long 8 #define uint unsigned int 9 #define il inline 10 #define jr 50000 11 #define P 10 12 using namespace std; 13 14 int n,m,now,pst,ex,ey; 15 int mp[N1][N1]; 16 int bar[N1]; 17 ll zip(int *a) 18 { 19 int cnt=0;ll ans=0; 20 memset(bar,-1,sizeof(bar)); 21 bar[0]=0; 22 for(int i=1;i<=m+1;i++){ 23 if(bar[a[i]]==-1) bar[a[i]]=++cnt; 24 ans=ans*P+bar[a[i]]; 25 }return ans; 26 } 27 void unzip(int *a,int *b,ll s,int &ma) 28 { 29 int cnt=0; 30 memset(bar,-1,sizeof(bar)); 31 for(int i=m+1;i>=1;i--) 32 a[i]=s%P,s/=P,ma=max(ma,a[i]); 33 for(int i=1;i<=m+1;i++) 34 if(a[i]){ 35 if(bar[a[i]]==-1) 36 bar[a[i]]=0,b[i]=0; 37 else 38 b[i]=1; 39 } 40 } 41 42 struct Hash{ 43 int head[M1],nxt[M1],cte; 44 ll to[M1],val[M1]; 45 void clr(){memset(head,0,sizeof(head));cte=0;} 46 void ae(ll u,ll v,int w) 47 { 48 cte++,to[cte]=v,val[cte]=w; 49 nxt[cte]=head[u],head[u]=cte; 50 } 51 int find(ll x) 52 { 53 ll y=x%jr,v; 54 for(int j=head[y];j;j=nxt[j]){ 55 v=to[j]; 56 if(v==x) return j; 57 }return 0; 58 } 59 void ins(ll x,ll w) 60 { 61 int i=find(x); 62 if(!i) ae(x%jr,x,0),i=cte; 63 val[i]+=w; 64 } 65 }h[2]; 66 67 ll ans; 68 int a[N1],bin[N1],tmp[N1]; 69 70 void init() 71 { 72 memset(a,0,sizeof(a)); 73 memset(h,0,sizeof(h)); 74 memset(mp,0,sizeof(mp)); 75 memset(bin,0,sizeof(bin)); 76 memset(tmp,0,sizeof(tmp)); 77 ans=0; 78 } 79 void push(int *t,ll w) 80 { 81 ll ans=0; 82 ans=zip(t); 83 h[now].ins(ans,w); 84 } 85 void solve(int x,int y) 86 { 87 h[now].clr(); 88 ll s,t,w; 89 int c[2],ma,fl; 90 for(int k=0;k<jr;k++) 91 for(int p=h[pst].head[k];p;p=h[pst].nxt[p]) 92 { 93 s=h[pst].to[p],ma=0; 94 unzip(a,bin,s,ma); 95 w=h[pst].val[p]; 96 if(!mp[x][y]) {h[now].ins(s,w);continue;} 97 for(int i=1;i<=m+1;i++) tmp[i]=a[i]; 98 if(a[y]&&!a[y+1]){ 99 if(mp[x+1][y]){push(tmp,w);} 100 if(mp[x][y+1]){tmp[y+1]=tmp[y],tmp[y]=0;push(tmp,w);} 101 }else if(!a[y]&&a[y+1]){ 102 if(mp[x][y+1]){push(tmp,w);} 103 if(mp[x+1][y]){tmp[y]=tmp[y+1],tmp[y+1]=0;push(tmp,w);} 104 }else if(!a[y]&&!a[y+1]){ 105 if(mp[x+1][y]&&mp[x][y+1]) 106 tmp[y]=tmp[y+1]=ma+1,push(tmp,w); 107 }else{ 108 if(!bin[y]&&!bin[y+1]){ 109 for(int j=y+2;j<=m+1;j++) 110 if(a[j]==a[y+1]) tmp[j]=tmp[y]; 111 }else if(bin[y]&&bin[y+1]){ 112 for(int j=1;j<=y-1;j++) 113 if(a[j]==a[y]) tmp[j]=tmp[y+1]; 114 }else if(bin[y]&&!bin[y+1]){ 115 for(int j=y+2;j<=m+1;j++) 116 if(a[j]==a[y+1]) tmp[j]=tmp[y]; 117 }else{ 118 fl=1; 119 for(int j=1;j<=y-1;j++) 120 if(a[j]) fl=0; 121 for(int j=y+2;j<=m+1;j++) 122 if(a[j]) fl=0; 123 if(x==ex&&y==ey&&fl) {ans+=w;continue;} 124 } 125 tmp[y]=tmp[y+1]=0; 126 push(tmp,w); 127 } 128 } 129 swap(now,pst); 130 } 131 void Enter() 132 { 133 h[now].clr(); 134 ll s,t,w; 135 int c[2],ma,fl; 136 for(int k=0;k<jr;k++) 137 for(int p=h[pst].head[k];p;p=h[pst].nxt[p]) 138 { 139 s=h[pst].to[p],ma=0; 140 unzip(a,bin,s,ma); 141 for(int i=1;i<=m+1;i++) tmp[i]=a[i]; 142 for(int i=m+1;i>=2;i--) tmp[i]=tmp[i-1]; 143 tmp[1]=0; 144 t=zip(tmp); 145 h[now].ins(t,h[pst].val[p]); 146 } 147 swap(now,pst); 148 } 149 150 int main() 151 { 152 freopen("t2.in","r",stdin); 153 int T; 154 scanf("%d",&T); 155 for(int t=1;t<=T;t++) 156 { 157 init(); 158 ex=ey=0; 159 scanf("%d%d",&n,&m); 160 for(int i=1;i<=n;i++){ 161 for(int j=1;j<=m;j++){ 162 scanf("%d",&mp[i][j]); 163 if(mp[i][j]) ex=i,ey=j; 164 } 165 } 166 now=1,pst=0; 167 h[pst].ins(0,1); 168 for(int i=1;i<=n;i++) 169 { 170 for(int j=1;j<=m;j++){ 171 solve(i,j); 172 }Enter(); 173 } 174 if(n==1&&m==1&&!mp[1][1]) ans=1; 175 printf("Case %d: There are %lld ways to eat the trees.\n",t,ans); 176 //printf("%lld\n",ans); 177 } 178 return 0; 179 }
#296 二维LIS (三维偏序CDQ)
外层按x排序,里层先按时间t分治,递归左区间,处理左区间对右区间的影响,递归右区间,回溯时重新按x排序

1 #include <vector> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define N1 100100 6 #define ll long long 7 #define dd double 8 #define inf 0x3f3f3f3f3f3f3f3fll 9 using namespace std; 10 11 int gint() 12 { 13 int ret=0,fh=1;char c=getchar(); 14 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 15 while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();} 16 return ret*fh; 17 } 18 int n,m,ma,nn,K; 19 20 struct BIT{ 21 int s[N1]; 22 void update(int x,int w){for(int i=x;i<=ma;i+=(i&(-i))) s[i]=max(s[i],w);} 23 int query(int x){int ans=0; for(int i=x;i;i-=(i&(-i))) ans=max(ans,s[i]); return ans;} 24 void clr(int x){for(int i=x;i<=ma;i+=(i&(-i))) s[i]=0;} 25 }b; 26 struct node{int x,y,t,ans;}a[N1],tmp[N1]; 27 int que[N1],tl; 28 29 void CDQ(int L,int R) 30 { 31 if(R-L<=1) return; 32 int M=(L+R)>>1,i=L,j=M,k,cnt=0; 33 for(k=L;k<R;k++) 34 if(a[k].t<M) tmp[i++]=a[k]; 35 else tmp[j++]=a[k]; 36 for(k=L;k<R;k++) a[k]=tmp[k]; 37 CDQ(L,M); 38 i=L,j=M; 39 while(i<M&&j<R) 40 { 41 if(a[i].x<a[j].x){ 42 b.update(a[i].y,a[i].ans); 43 que[++tl]=i; i++; 44 }else{ 45 a[j].ans=max(a[j].ans,b.query(a[j].y-1)+1); 46 j++; 47 } 48 } 49 while(j<R) {a[j].ans=max(a[j].ans,b.query(a[j].y-1)+1); j++;} 50 while(tl) b.clr(a[que[tl--]].y); 51 CDQ(M,R); 52 i=L,j=M,cnt=0; 53 while(i<M&&j<R) 54 { 55 if(a[i].x<a[j].x){ 56 tmp[++cnt]=a[i]; i++; 57 }else{ 58 tmp[++cnt]=a[j]; j++; 59 } 60 } 61 while(i<M) {tmp[++cnt]=a[i]; i++;} 62 while(j<R) {tmp[++cnt]=a[j]; j++;} 63 for(k=L;k<R;k++) a[k]=tmp[k-L+1]; 64 } 65 int cmp(node s1,node s2){return s1.x<s2.x;} 66 67 int main() 68 { 69 scanf("%d",&n); 70 int i,j,x,y,ans=0; 71 for(i=1;i<=n;i++) a[i].x=gint(),a[i].y=gint(),a[i].t=i,a[i].ans=1,ma=max(ma,a[i].y); 72 sort(a+1,a+n+1,cmp); 73 CDQ(1,n+1); 74 for(i=1;i<=n;i++) ans=max(ans,a[i].ans); 75 printf("%d\n",ans); 76 return 0; 77 }
2019.1.7
BZOJ 5332 [SDOI2018]旧试题 (莫比乌斯反演)
题目大意:略
shadowice神犇的题解写得太好了,非常通俗易懂,佩服的五体投地Orzzz
感觉我都没啥好补充的
不过我删去一些判定条件之后,答案依然正确,很迷啊,大概是因为莫比乌斯函数会把多出来的部分容斥掉吧

1 #include <vector> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define N1 101000 6 #define S1 1601000 7 #define ll long long 8 #define dd double 9 using namespace std; 10 11 const int maxn=100000; 12 const ll jr=1000000007; 13 14 void exgcd(ll a,ll b,ll &x,ll &y) 15 { 16 if(!b){ x=1; y=0; return; } 17 exgcd(b,a%b,x,y); ll t=x; x=y; y=t-a/b*y; 18 } 19 20 int A,B,C,T; 21 int use[N1],pr[N1],mu[N1],cnt; 22 int xx[S1],yy[S1],ww[S1],ouc[N1]; 23 ll fa[N1],fb[N1],fc[N1]; 24 vector<int>son[N1]; 25 struct node{int to,val;}; 26 vector<node>e[N1]; 27 28 void get_mu() 29 { 30 int i,j; mu[1]=1; use[1]=1; 31 for(use[1]=1,i=2;i<=maxn;i++) 32 { 33 if(!use[i]){ pr[++cnt]=i; mu[i]=-1; } 34 for(j=1;j<=cnt&&i*pr[j]<=maxn;j++) 35 { 36 use[i*pr[j]]=1; 37 if(i%pr[j]){ mu[i*pr[j]]=-mu[i]; } 38 else break; 39 } 40 } 41 for(i=1;i<=maxn;i++) 42 { 43 for(j=i;j<=maxn;j+=i) 44 { 45 if(mu[j]&&!use[i]) son[j].push_back(i); 46 } 47 } 48 } 49 void init() 50 { 51 int i,j,s,t,sz,x,y; 52 for(i=1;i<=C;i++) 53 { 54 for(fa[i]=fb[i]=fc[i]=0,j=i;j<=C;j+=i) 55 { 56 fa[i]+=A/j; fb[i]+=B/j; fc[i]+=C/j; 57 } 58 fa[i]%=jr; fb[i]%=jr; fc[i]%=jr; 59 } 60 for(i=1,cnt=0;i<=C;i++) 61 { 62 if(!mu[i]) continue; sz=son[i].size(); 63 for(s=0;s<(1<<sz);s++) 64 { 65 for(j=0,x=1;j<sz;j++) if(s&(1<<j)) x*=son[i][j]; 66 for(t=s;t;(--t)&=s) 67 { 68 for(j=0,y=1;j<sz;j++) if(t&(1<<j)) y*=son[i][j]; 69 cnt++; xx[cnt]=x; yy[cnt]=1ll*i*y/x; ww[cnt]=i; ouc[x]++; 70 } 71 cnt++; xx[cnt]=x; yy[cnt]=1ll*i/x; ww[cnt]=i; ouc[x]++; 72 } 73 } 74 for(i=1;i<=cnt;i++) 75 { 76 x=xx[i]; y=yy[i]; 77 if(ouc[x]>ouc[y]||(ouc[x]==ouc[y]&&x<y)) e[x].push_back((node){y,ww[i]}); 78 } 79 } 80 void clr() 81 { 82 memset(ouc,0,sizeof(ouc)); 83 for(int i=1;i<=maxn;i++) e[i].clear(); 84 } 85 86 int ok[N1]; 87 88 int main() 89 { 90 freopen("t2.in","r",stdin); 91 scanf("%d",&T); get_mu(); 92 while(T--){ 93 scanf("%d%d%d",&A,&B,&C); 94 if(A>B) swap(A,B); if(A>C) swap(A,C); if(B>C) swap(B,C); 95 int i,j,k,x,y,z; clr(); init(); ll lxy,lyz,lzx,ans=0,sum; 96 for(i=1;i<=C;i++) 97 { 98 x=i; 99 for(j=0;j<e[x].size();j++) 100 { 101 y=(e[x][j]).to; 102 ok[y]=(e[x][j]).val; 103 } 104 for(j=0;j<e[x].size();j++) 105 { 106 y=(e[x][j]).to; lxy=(e[x][j]).val; 107 for(k=0;k<e[y].size();k++) 108 { 109 z=(e[y][k]).to; if(!ok[z]) continue; 110 lyz=(e[y][k]).val; lzx=ok[z]; sum=0; 111 /*if(lzx<=A&&lxy<=B&&lyz<=C&&x<=A&&y<=B&&z<=A) sum+=1ll*fa[lzx]*fb[lxy]%jr*fc[lyz]%jr; 112 if(lxy<=A&&lzx<=B&&lyz<=C&&x<=A&&y<=A&&z<=B) sum+=1ll*fa[lxy]*fb[lzx]%jr*fc[lyz]%jr; 113 if(lyz<=A&&lxy<=B&&lzx<=C&&x<=B&&y<=A&&z<=A) sum+=1ll*fa[lyz]*fb[lxy]%jr*fc[lzx]%jr; 114 if(lxy<=A&&lyz<=B&&lzx<=C&&x<=A&&y<=A&&z<=B) sum+=1ll*fa[lxy]*fb[lyz]%jr*fc[lzx]%jr; 115 if(lyz<=A&&lzx<=B&&lxy<=C&&x<=B&&y<=A&&z<=A) sum+=1ll*fa[lyz]*fb[lzx]%jr*fc[lxy]%jr; 116 if(lzx<=A&&lyz<=B&&lxy<=C&&x<=A&&y<=B&&z<=A) sum+=1ll*fa[lzx]*fb[lyz]%jr*fc[lxy]%jr;*/ 117 sum=(fa[lzx]*fb[lxy]%jr*fc[lyz]+fa[lxy]*fb[lzx]%jr*fc[lyz]+fa[lyz]*fb[lxy]%jr*fc[lzx]+fa[lxy]*fb[lyz]%jr*fc[lzx]+fa[lyz]*fb[lzx]%jr*fc[lxy]+fa[lzx]*fb[lyz]%jr*fc[lxy])%jr*mu[x]*mu[y]*mu[z]; 118 ans=(ans+sum+jr)%jr; 119 } 120 /*if(x<=A&&y<=A&&lxy<=A) sum+=1ll*fa[lxy]*fb[x]%jr*fc[lxy]%jr+1ll*fa[lxy]*fb[lxy]%jr*fc[x]%jr; 121 if(x<=A&&y<=B&&lxy<=B) sum+=1ll*fa[x]*fb[lxy]%jr*fc[lxy]%jr;*/ 122 sum=(fa[lxy]*fb[x]%jr*fc[lxy]+fa[lxy]*fb[lxy]%jr*fc[x]+fa[x]*fb[lxy]%jr*fc[lxy])%jr*mu[y]; 123 ans=(ans+sum+jr)%jr; 124 /*if(y<=A&&x<=A&&lxy<=A) sum+=1ll*fa[lxy]*fb[y]%jr*fc[lxy]%jr+1ll*fa[lxy]*fb[lxy]%jr*fc[y]%jr; 125 if(y<=A&&x<=B&&lxy<=B) sum+=1ll*fa[y]*fb[lxy]%jr*fc[lxy]%jr;*/ 126 sum=(fa[lxy]*fb[y]%jr*fc[lxy]+fa[lxy]*fb[lxy]%jr*fc[y]+fa[y]*fb[lxy]%jr*fc[lxy])%jr*mu[x]; 127 ans=(ans+sum+jr)%jr; 128 } 129 for(j=0;j<e[x].size();j++) 130 { 131 y=(e[x][j]).to; 132 ok[y]=0; 133 } 134 /*if(x<=A)*/ ans=(ans+1ll*fa[x]*fb[x]%jr*fc[x]%jr*mu[x]+jr)%jr; 135 } 136 printf("%lld\n",ans); 137 } 138 return 0; 139 }
2019.1.10
BZOJ 2242 [SDOI2011]计算器 (BSGS)
BSGS板子题,没啥好解释的
注意逆元不存在的情况,Y%p==0

1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define N1 200010 6 #define M1 40010 7 #define ll long long 8 #define dd double 9 #define cll const long long 10 #define inf 0x3f3f3f3f 11 using namespace std; 12 13 int T,K; 14 ll qpow(ll x,int y,int mod) 15 { 16 ll ans=1; 17 while(y){ 18 if(y&1){ ans=ans*x%mod; } 19 x=x*x%mod; y>>=1; 20 }return ans; 21 } 22 void solve1(int y,int z,int p) 23 { 24 ll ans=qpow(y,z,p); 25 printf("%lld\n",ans); 26 } 27 28 int gcd(int x,int y){ if(!y) return x; return gcd(y,x%y); } 29 void exgcd(ll a,ll b,ll &x,ll &y) 30 { 31 if(!b){ x=1; y=0; return; } 32 exgcd(b,a%b,x,y); ll t=x; x=y; y=t-a/b*y; 33 } 34 void solve2(ll y,ll z,ll p) 35 { 36 ll x,inv,invy,ans; int g=gcd(y,p); z%=p; 37 if(z%g!=0) 38 { 39 puts("Orz, I cannot find x!"); 40 return; 41 } 42 y/=g; p/=g; z/=g; 43 exgcd(y,p,inv,invy); inv=(inv%p+p)%p; 44 ans=inv*z%p; p*=g; 45 ans=ans*g%p; 46 printf("%lld\n",ans); 47 } 48 49 struct Hsh{ 50 #define maxn 200000 51 int head[N1],to[M1],val[M1],nxt[M1],cte; 52 void ins(int x,int w) 53 { 54 int u=x%maxn,j,v; 55 for(j=head[u];j;j=nxt[j]) 56 { 57 v=to[j]; 58 if(v==x) return; 59 } 60 cte++; to[cte]=x; val[cte]=w; 61 nxt[cte]=head[u]; head[u]=cte; 62 } 63 int find(int x) 64 { 65 int u=x%maxn,j,v; 66 for(j=head[u];j;j=nxt[j]) 67 { 68 v=to[j]; 69 if(v==x) return val[j]; 70 } 71 return -1; 72 } 73 #undef maxn 74 }h; 75 void solve3(int y,int z,int p) 76 { 77 int i,sq=sqrt(p),pw=qpow(y,sq,p),ans=inf,tmp,now; z%=p; 78 if(y%p==0){ puts("Orz, I cannot find x!"); return; } 79 for(now=qpow(y,sq-1,p),i=1;sq*(i-1)-1<p;i++) 80 { 81 h.ins(now,i); 82 now=1ll*now*pw%p; 83 } 84 for(now=z,i=0;i<sq;i++) 85 { 86 tmp=h.find(now); 87 if(tmp!=-1) ans=min(ans,tmp*sq-1-i); 88 now=1ll*now*y%p; 89 } 90 if(ans==inf) puts("Orz, I cannot find x!"); 91 else printf("%d\n",ans); 92 memset(&h,0,sizeof(h)); 93 } 94 95 int main() 96 { 97 scanf("%d%d",&T,&K); 98 int y,z,p; 99 while(T--) 100 { 101 scanf("%d%d%d",&y,&z,&p); 102 if(K==1) solve1(y,z,p); 103 if(K==2) solve2(y,z,p); 104 if(K==3) solve3(y,z,p); 105 } 106 return 0; 107 }