zoukankan      html  css  js  c++  java
  • [校内训练20_10_13]ABC

    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('
    ');
     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
  • 相关阅读:
    小菜编程成长记(十四 设计模式不能戏说!设计模式怎就不能戏说?)
    小菜编程成长记(十三 有了门面,程序员的程序会更加体面!)
    伍迷随想冷饭集 之 手术前后之随想
    伍迷随想冷饭集 之 自动扶梯之随想
    小菜编程成长记(十一 三层架构,分层开发)
    伍迷随想冷饭集 之 固定晚餐之随想
    伍迷随想冷饭集 之 瞻前顾后之随想
    伍迷随想冷饭集 之 北国冬天之随想
    伍迷随想冷饭集 之 漫游大理国之随想
    伍迷随想冷饭集 之 伍迷运动之随想
  • 原文地址:https://www.cnblogs.com/GreenDuck/p/13808272.html
Copyright © 2011-2022 走看看