A.求矩阵的秩。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long int ll;
 4 int n,m;
 5 ll a[205][205],b[205][205];
 6 inline ll qpow(ll x,ll y,ll mod)
 7 {
 8     ll ans=1,base=x;
 9     while(y)
10     {
11         if(y&1)
12             ans=ans*base%mod;
13         base=base*base%mod;
14         y>>=1;
15     }
16     return ans;
17 }
18 inline void add(ll&x,ll y,ll mod)//!!!!!!!!!!!!!!
19 {
20     x=(x+y)%mod;
21 }
22 inline int test(ll mod)
23 {
24     for(int i=1;i<=n;++i)
25         for(int j=1;j<=m;++j)
26             b[i][j]=a[i][j];
27     for(int i=1;i<=m;++i)
28     {
29         bool ok=0;
30         for(int j=i;j<=n;++j)
31             if(b[j][i])
32             {
33                 swap(b[i],b[j]);
34                 ok=1;
35                 break;
36             }
37         if(!ok)
38             return i-1;
39         ll s=qpow(b[i][i],mod-2,mod);
40         for(int j=i+1;j<=n;++j)
41         {
42             ll g=(mod-b[j][i]*s%mod)%mod;
43             for(int k=i;k<=m;++k)
44                 add(b[j][k],b[i][k]*g,mod);
45         }
46     }
47     return m;
48 }
49 int main()
50 {
51 //    freopen("kangaroo.in","r",stdin);
52 //    freopen("kangaroo.out","w",stdout);
53     ios::sync_with_stdio(false);
54     cin>>n>>m;
55     for(int i=1;i<=n;++i)
56         for(int j=1;j<=m;++j)
57             cin>>a[i][j];
58     if(n<m)
59     {
60         for(int i=1;i<=n;++i)
61             for(int j=i;j<=m;++j)
62                 swap(a[i][j],a[j][i]);
63         swap(n,m);
64     }
65     cout<<max(max(max(test(998244353),test(1000000007)),test(19260817)),test(1145141))<<endl;
66     return 0;
67 }
View Code

B.给出一个树,树上节点u能到达后代节点v当且仅当a[u]是a[v]的倍数,求1到所有节点的路径数。数字的约数个数不超过100000。

考虑如下两种方法:

1.dfs时,每次到达一个节点时用O(1)从bucket中获得答案,然后花O(d)时间更新bucket(找到所有约数)。

2.dfs时,每次到达一个节点时用O(d)时间访问bucket中的所有可能的倍数,然后O(1)更新数组。

为了降低复杂度,我们可以将一个数字分为两部分:前半部分用来更新数组,使用算法1;后半部分用来统计答案,使用算法2。

这就是csp初赛的最后一题。

  1 #include<bits/stdc++.h>
  2 #define mod 1000000007
  3 using namespace std;
  4 typedef long long int ll;
  5 typedef long double ld;
  6 const int maxn=1E5+5;
  7 int n,size,head[maxn];
  8 ll a[maxn],ans[maxn];
  9 int totP,limit,buf[21],up[21],b[maxn][21];
 10 struct edge
 11 {
 12     int to,next;
 13 }E[maxn*2];
 14 inline ll read()
 15 {
 16     char ch=getchar();
 17     while(!isdigit(ch))ch=getchar();
 18     ll s=ch-'0';ch=getchar();
 19     while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
 20     return s;
 21 }
 22 int G[55];
 23 inline void write(ll x)
 24 {
 25     int g=0;
 26     do{G[++g]=x%10;x/=10;}while(x);
 27     for(int i=g;i>=1;--i)putchar('0'+G[i]);putchar('\n');
 28 }
 29 inline void add(int u,int v)
 30 {
 31     E[++size].to=v;
 32     E[size].next=head[u];
 33     head[u]=size;
 34 }
 35 int tmp[21];
 36 ll bucket[10000005];
 37 int pre[maxn];
 38 ll getAns(int u,int s,int now)
 39 {
 40     if(s>limit)
 41     {
 42         if(!pre[u])
 43             while(s<totP)
 44             {
 45                 pre[u]+=b[u][s]*buf[s];
 46                 ++s;
 47             }
 48         now+=pre[u];
 49         return bucket[now];
 50     }
 51     ll sum=0;
 52     now+=buf[s]*b[u][s];
 53     for(int i=b[u][s];i<=up[s];++i,now+=buf[s])
 54         sum+=getAns(u,s+1,now);
 55     return sum;
 56 }
 57 void addAns(int u,int s,int now,ll x,bool flag)
 58 {
 59     if(s==totP)
 60     {
 61         if(flag)
 62         {
 63             bucket[now]+=x;
 64             if(bucket[now]>=mod)
 65                 bucket[now]-=mod;
 66         }
 67         else
 68         {
 69             bucket[now]-=x;
 70             if(bucket[now]<0)
 71                 bucket[now]+=mod;
 72         }
 73         return;
 74     }
 75     if(s<=limit)
 76     {
 77         while(s<=limit)
 78         {
 79             now+=b[u][s]*buf[s];
 80             ++s;
 81         }
 82         addAns(u,s,now,x,flag);
 83     }
 84     else
 85         for(int i=0;i<=b[u][s];++i,now+=buf[s])
 86             addAns(u,s+1,now,x,flag);
 87 } 
 88 void dfs(int u,int F)
 89 {
 90     if(u==1)
 91         ans[u]=1;
 92     else
 93         ans[u]=getAns(u,0,0)%mod;
 94     addAns(u,0,0,ans[u],1);
 95     for(int i=head[u];i;i=E[i].next)
 96     {
 97         int v=E[i].to;
 98         if(v==F)
 99             continue;
100         dfs(v,u);
101     }
102     addAns(u,0,0,ans[u],0);
103 }
104 namespace MATH
105 {
106     const int len=10;
107     const int test[len]={2,3,5,7,11,13,17,19,23,29};
108     inline ll mul(ll x,ll y,ll M)
109     {
110         return (ll(x*y-(ll((ld)x*y/M))*M)%M+M)%M;
111     }
112     inline ll qpow(ll x,ll y,ll M)
113     {
114         ll ans=1,base=x;
115         while(y)
116         {
117             if(y&1)
118                 ans=mul(ans,base,M);
119             base=mul(base,base,M);
120             y>>=1;
121         }
122         return ans;
123     }
124     inline bool miller(ll x)
125     {
126         for(int i=0;i<len;++i)
127         {
128             if(x<test[i])
129                 return false;
130             else if(x==test[i])
131                 return true;
132             ll now=qpow(test[i],x-1,x),g=x-1;
133             if(now!=1)
134                 return false;
135             while(now==1&&!(g&1))
136             {
137                 g>>=1;
138                 now=qpow(test[i],g,x);
139                 if(now!=1&&now!=x-1)
140                     return false;
141             }
142         }
143         return true;
144     }
145     ll gcd(ll x,ll y)
146     {
147         return x%y==0?y:gcd(y,x%y);
148     }
149     inline ll f(ll x,ll y,ll M)
150     {
151         return (mul(x,x,M)+y)%M;
152     }
153     inline ll get(ll n,ll c,int steps)
154     {
155         if(!(n&1))
156             return 2;
157         ll x=2,y=2,d=1;
158         while(true)
159         {
160             ll tmpx=x,tmpy=y;
161             for(int i=1;i<=steps;++i)
162             {
163                 x=f(x,c,n);
164                 y=f(y,c,n);
165                 y=f(y,c,n);
166                 d=mul(d,((y-x)%n+n)%n,n);
167             }
168             d=gcd(d,n);
169             if(d==1)
170                 continue;
171             if(d!=n)
172                 return d;
173             x=tmpx,y=tmpy;
174             for(int i=1;i<=steps;++i)
175             {
176                 x=f(x,c,n);
177                 y=f(y,c,n);
178                 y=f(y,c,n);
179                 d=gcd(((y-x)%n+n)%n,n);
180                 if(d!=1&&d!=n)
181                     return d;
182             }
183             return 0;
184         }
185     }
186     vector<ll>wait;
187     void pollard(ll n)
188     {
189         if(miller(n))
190         {
191             wait.push_back(n);
192             return;
193         }
194         ll now=0,c=1,g=pow(n,0.1)+1;
195         while(!now)
196             now=get(n,++c,g);
197         pollard(now),pollard(n/now);
198     }
199     int prime[555];
200     void main()
201     {
202         if(a[1]!=1)
203             pollard(a[1]);
204         sort(wait.begin(),wait.end());
205         int last=-1;
206         for(int i=0;i<wait.size();++i)
207         {
208             if(wait[i]!=last)
209             {
210                 ++up[totP]; 
211                 prime[totP++]=wait[i];
212             }
213             else
214                 ++up[totP-1];
215             last=wait[i];
216         }
217         buf[totP-1]=1;
218         for(int i=totP-2;i>=0;--i)
219             buf[i]=buf[i+1]*(up[i+1]+1);
220         int s=up[0]+1,now=buf[0];
221         limit=0;
222         for(int i=1;i<totP;++i)
223         {
224             if(max(s,buf[0]/s)<now)
225             {
226                 now=max(s,buf[0]/s);
227                 limit=i;
228             }
229             s*=up[i]+1;
230         }
231         for(int u=1;u<=n;++u)
232         {
233             ll x=a[u];
234             for(int i=0;i<totP;++i)
235                 while(x%prime[i]==0)
236                 {
237                     x/=prime[i];
238                     ++b[u][i];
239                 }
240         }
241         /*
242         cout<<"PRIME : ";
243         for(int i=0;i<totP;++i)
244             cout<<prime[i]<<" ";cout<<endl;
245         for(int u=1;u<=n;++u)
246         {
247             cout<<u<<" : ";
248             for(int i=0;i<totP;++i)
249                 cout<<b[u][i]<<" ";cout<<endl;
250         }
251         cout<<"LIMIT : "<<limit<<endl;
252         */
253     }
254 }
255 inline void init()
256 {
257     MATH::main();
258 }
259 inline void solve()
260 {
261     init();
262     dfs(1,0);
263     for(int i=1;i<=n;++i)
264         write((ans[i]%mod+mod)%mod);
265 }
266 int main()
267 {
268     freopen("walk.in","r",stdin);
269     freopen("walk.out","w",stdout);
270     ios::sync_with_stdio(false);
271     n=read();
272     for(int i=2;i<=n;++i)
273     {
274         int x=read(),y=read();
275         add(x,y);
276         add(y,x);
277     }
278     for(int i=1;i<=n;++i)
279         a[i]=read();
280     solve();
281     return 0;
282 }
View Code

C.三元环计数

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef unsigned long long ull;
  4 const int maxn=2E5+5;
  5 int n,m;
  6 int size,head[maxn];
  7 int size2,head2[maxn],deg[maxn];
  8 ull A,B,C,ans,a[maxn],sum[maxn];
  9 inline int read()
 10 {
 11     char ch=getchar();
 12     while(!isdigit(ch))ch=getchar();
 13     int s=ch-'0';ch=getchar();
 14     while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
 15     return s;
 16 }
 17 struct edge
 18 {
 19     int to,next;
 20 }E[maxn*2],E2[maxn*2];
 21 inline void add(int u,int v)
 22 {
 23     E[++size].to=v;
 24     E[size].next=head[u];
 25     head[u]=size;
 26 }
 27 inline void add2(int u,int v)
 28 {
 29     E2[++size2].to=v;
 30     E2[size2].next=head2[u];
 31     head2[u]=size2;
 32 }
 33 inline ull C2(int x)
 34 {
 35     return (ull)x*(x-1)/2;
 36 }
 37 inline void get0()
 38 {
 39     for(int i=0;i<n;++i)
 40     {
 41         ans+=A*i*C2(n-i-1);
 42         ans+=B*i*i*(n-i-1);
 43         ans+=C*i*C2(i);
 44     }
 45 }
 46 inline void get1()
 47 {
 48     for(int u=0;u<n;++u)
 49         for(int e=head[u];e;e=E[e].next)
 50         {
 51             int v=E[e].to;
 52             if(u>v)
 53                 continue;
 54             int x=u,y=v;
 55             ans-=(ull)(n-y-1)*(A*x+B*y)+C*(sum[n-1]-sum[y]);
 56             ans-=(ull)(y-x-1)*(A*x+C*y)+B*(sum[y-1]-sum[x]);
 57             if(x)
 58                 ans-=(ull)(x)*(B*x+C*y)+A*(sum[x-1]);
 59         }
 60 }
 61 int tmpL[maxn],tmpR[maxn];
 62 inline void get2()
 63 {
 64     for(int u=0;u<n;++u)
 65     {
 66         int totL=0,totR=0;
 67         ull sumL=0,sumR=0;
 68         for(int e=head[u];e;e=E[e].next)
 69         {
 70             int v=E[e].to;
 71             if(v<u)
 72                 tmpL[++totL]=v;
 73             else
 74                 tmpR[++totR]=v;
 75         }
 76         ans+=B*u*totL*totR;
 77         
 78         sort(tmpL+1,tmpL+totL+1);
 79         sort(tmpR+1,tmpR+totR+1);
 80         
 81         for(int i=1;i<=totL;++i)
 82         {
 83             ans+=A*tmpL[i]*totR;
 84             ans+=A*tmpL[i]*(totL-i);
 85             ans+=B*tmpL[i]*(i-1);
 86         }
 87         ans+=C*u*C2(totL);
 88         
 89         for(int i=1;i<=totR;++i)
 90         {
 91             ans+=C*tmpR[i]*totL;
 92             ans+=B*tmpR[i]*(totR-i);
 93             ans+=C*tmpR[i]*(i-1);
 94         }
 95         ans+=A*u*C2(totR);
 96     }
 97 }
 98 int TI,color[maxn];
 99 inline void get3()
100 {
101     for(int u=0;u<n;++u)
102         for(int i=head[u];i;i=E[i].next)
103         {
104             int v=E[i].to;
105             if(deg[u]==deg[v]&&u>v)
106                 add2(u,v);
107             else if(deg[u]>deg[v])
108                 add2(u,v);
109         }
110     for(int u=0;u<n;++u)
111     {
112         ++TI;
113         for(int i=head2[u];i;i=E2[i].next)
114             color[E2[i].to]=TI;
115         for(int i=head2[u];i;i=E2[i].next)
116         {
117             int v=E2[i].to;
118             for(int j=head2[v];j;j=E2[j].next)
119             {
120                 int w=E2[j].to;
121                 if(color[w]==TI)
122                 {
123                     int x=min(min(u,v),w);
124                     int y=max(max(u,v),w);
125                     int z=u;
126                     if(x!=u&&y!=u)
127                         z=u;
128                     else if(x!=v&&y!=v)
129                         z=v;
130                     else
131                         z=w;
132                     ans-=A*x+B*z+C*y;
133                 }
134             }
135         }
136     }
137 }
138 int main()
139 {
140     freopen("girls.in","r",stdin);
141     freopen("girls.in","r",stdin);
142     ios::sync_with_stdio(false);
143     n=read(),m=read(),A=read(),B=read(),C=read(); 
144     for(int i=1;i<=m;++i)
145     {
146         int x=read(),y=read();
147         add(x,y);
148         add(y,x);
149         ++deg[x],++deg[y];
150     }
151     for(int i=1;i<n;++i)
152         sum[i]=sum[i-1]+i;
153     get0();
154     get1();
155     get2();
156     get3();
157     cout<<ans<<endl;
158     return 0;
159 }
View Code

 

 posted on 2020-10-13 13:38  GreenDuck  阅读(148)  评论(0编辑  收藏  举报