省选前作业题汇总2

一些CC题

(完全口胡预警

Milestones

直接随机直线即可,两个点正好在那条直线上的概率是$frac{1}{49}$

Knight Moving

a,b线性无关:解方程之后转成网格图上路径计数

a,b线性相关:点数不超过2*500,直接建图路径计数

(别看就两句,i207M码了8个K,我先跑了

Product of Digitals

质因数分解后本质就是$2,3,5,7$的若干次方相乘

BSGS的思想,预处理$2,3$的次幂并排序,枚举$5,7$的次幂二分找有没有对应的$2,3$

Sine Partition Function

这什么玩意

神tm矩乘,咕咕咕

Reduce string

BZOJ 2121 $O(n^3*m*len)$大力DP


一些THUPC题

Tommy神的树

orz immortalCO,咕咕咕

赛艇

*AUWC,这是好的*

两个0/1矩阵的交为全零矩阵->对应位置没有交->展开成序列->通过序列对应位置相乘(0/1的乘法相当于与运算)判断->反转序列使得对差的位置做贡献->成功把状态压缩在一个格子里->多项式乘法

就是下标调的很烦啊=。=

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cctype>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 const int N=1550,M=9e6+90,mod=998244353;
 8 int a[M],b[M],rev[M],pw[30][2]; char rd[M];
 9 int n,m,k,mx,my,nx,ny,xx,yy,nm,ans,G,Gi;
10 int Qpow(int x,int k)
11 {
12     if(k==1) return x;
13     int tmp=Qpow(x,k/2);
14     return k%2?1ll*tmp*tmp%mod*x%mod:1ll*tmp*tmp%mod;
15 }
16 int ID(int a,int b)
17 {
18     return a*m+b;
19 }
20 int IDX()
21 {
22     return (xx-mx)*m+yy-my;
23 }
24 void Pre()
25 {
26     register int i; 
27     nm=1; while(nm<=2*n*m) nm<<=1;
28     for(i=1;i<nm;i++)
29         rev[i]=(rev[i>>1]>>1)+(i&1)*(nm>>1);
30     G=3,Gi=Qpow(G,mod-2),nx-=mx,ny-=my;
31     for(int i=1;i<=28;i++)
32     {
33         pw[i][0]=Qpow(G,(mod-1)/(1<<i));
34         pw[i][1]=Qpow(Gi,(mod-1)/(1<<i));
35     }
36 }
37 void Trans(int *arr,int len,int typ)
38 {
39     register int i,j,k;
40     for(i=0;i<len;i++)
41         if(rev[i]>i) swap(arr[rev[i]],arr[i]);
42     for(i=2;i<=len;i<<=1)
43     {
44         int lth=i>>1,ort=pw[(int)log2(i)][typ==-1];
45         for(j=0;j<len;j+=i)
46         {
47             int ori=1,tmp;
48             for(k=j;k<j+lth;k++,ori=1ll*ori*ort%mod)
49             {
50                 tmp=1ll*ori*arr[k+lth]%mod;
51                 arr[k+lth]=(arr[k]-tmp+mod)%mod;
52                 arr[k]=(arr[k]+tmp)%mod;
53             }
54         }
55     }
56     if(typ==-1)
57     {
58         int Ni=Qpow(len,mod-2);
59         for(i=0;i<=len;i++)
60             arr[i]=1ll*arr[i]*Ni%mod;
61     }
62 }
63 int main()
64 {
65     register int i;
66     scanf("%d%d%d",&n,&m,&k);
67     for(int i=0;i<n;i++)
68     {
69         scanf("%s",rd);
70         for(int j=0;j<m;j++)
71             a[ID(i,j)]=rd[j]=='1';
72     }
73     scanf("%s",rd);
74     for(int i=0;i<k;i++)
75     {
76         if(rd[i]=='w') xx--; if(rd[i]=='a') yy--;
77         if(rd[i]=='s') xx++; if(rd[i]=='d') yy++;
78         mx=min(mx,xx),nx=max(nx,xx);
79         my=min(my,yy),ny=max(ny,yy);
80     }
81     xx=yy=0,b[IDX()]=1;
82     for(int i=0;i<k;i++)
83     {
84         if(rd[i]=='w') xx--; if(rd[i]=='a') yy--;
85         if(rd[i]=='s') xx++; if(rd[i]=='d') yy++;
86         b[IDX()]=1;
87     }//printf("%d %d %d %d ",nx,mx,ny,my);
88     reverse(b,b+n*m),Pre(); 
89 //    for(int i=0;i<n*m;i++)
90 //        printf("%d %d
",a[i],b[i]);
91     Trans(a,nm,1),Trans(b,nm,1);
92     for(i=0;i<nm;i++) a[i]=1ll*a[i]*b[i]%mod;
93     Trans(a,nm,-1); //printf("%d %d ",n-nx,m-ny);
94     for(int i=0;i<n-nx;i++)
95         for(int j=0;j<m-ny;j++)
96             if(!a[i*m+j+n*m-1]) ans++;
97     printf("%d",ans);
98     return 0;
99 }
View Code

蛋糕

特判掉测度为1的情况,之后状压每一维是否在边界,枚举子集统计

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define ull unsigned long long
 5 using namespace std;
 6 const int N=20;
 7 const ull mod=2148473648;
 8 int T,S,B,cnt[N],wid[N];
 9 ull ans[N];
10 void Add(ull &x,ull y)
11 {
12     x+=y;
13     if(x>=mod) x-=mod;
14 }
15 ull Count(int s)
16 {
17     ull ret=1;
18     for(int i=0;i<4;i++)
19         if(wid[i]!=1)
20         {
21             if(s&(1<<i)) ret=ret*2%mod;
22             else ret=ret*(wid[i]-2)%mod;
23         }
24     return ret;
25 }
26 int main()
27 {
28     for(int i=0;i<=(1<<4);i++)
29         cnt[i]=cnt[i>>1]+(i&1);
30     scanf("%d",&T);
31     while(T--)
32     {
33         memset(ans,S=B=0,sizeof ans);
34         for(int i=0;i<4;i++)
35         {
36             scanf("%d",&wid[i]);
37             (wid[i]==1)?B+=2:S|=1<<i;
38         }
39         for(int s=S;;s=(s-1)&S)
40         {
41             Add(ans[B+cnt[s]],Count(s));
42             if(!s) break;
43         }
44         for(int i=0;i<=8;i++)
45             printf("%llu ",ans[i]); puts("");
46     }
47     return 0;
48 }
View Code

RSA

$∵gcd(e1,e2)==1$

$∴m->m^1->m^{e_1*x+e_2*y}->m^{{e_1}^x}*m^{{e_2}^y}->c_1^x*c_2^y$,类似exGCD那样求解,即递归求$gcd(e1,e2)$,过程中不断更新$c1,c2->c2,c1*Inv(c2^{e1/e2})$

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define ll long long
 5 using namespace std;
 6 ll T,c1,c2,e1,e2,mod;
 7 void Add(ll &x,ll y)
 8 {
 9     x+=y;
10     if(x>=mod) x-=mod;
11 }
12 void exGCD(ll a,ll b,ll &x,ll &y)
13 {
14     if(!b) x=1,y=0;
15     else exGCD(b,a%b,y,x),y-=a/b*x;
16 }
17 ll Inv(ll x)
18 {
19     ll xx,yy;
20     exGCD(x,mod,xx,yy);
21     return (xx%mod+mod)%mod;
22 }
23 ll llm(ll a,ll b)
24 {
25     ll ret=0;
26     while(b)
27     {
28         if(b&1) Add(ret,a);
29         Add(a,a),b>>=1;
30     }
31     return ret;
32 }
33 ll Qpow(ll x,ll k)
34 {
35     ll ret=1;
36     while(k)
37     {
38         if(k&1) ret=llm(ret,x);
39         x=llm(x,x),k>>=1;
40     }
41     return ret;
42 }
43 void Solve(ll a,ll b)
44 {
45     if(b) 
46     {
47         ll n1=c2,n2=llm(c1,Inv(Qpow(c2,a/b)));
48         c1=n1,c2=n2,Solve(b,a%b);
49     }
50 }
51 int main()
52 {
53     scanf("%lld",&T);
54     while(T--)
55     {
56         scanf("%lld%lld%lld%lld%lld",&c1,&c2,&e1,&e2,&mod);
57         Solve(e1,e2),printf("%lld
",c1);
58     }
59     return 0;
60 }
View Code
原文地址:https://www.cnblogs.com/ydnhaha/p/10452711.html