简短题解集合

有一些题比较水没什么新意,就懒得写长题解了

 

忘了日期的

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 }
View Code

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 }
View Code

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 }
View Code

#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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

posted @ 2018-12-01 16:42  guapisolo  阅读(192)  评论(0)    收藏  举报