2020_10_05:

A.没意思。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long int ll;
 4 const ll inf=1E18;
 5 int n,m,totC;
 6 ll f[2005*50],g[2005*50];
 7 struct pt
 8 {
 9     int type,c;
10     ll w,v;
11     bool operator<(const pt&A)const
12     {
13         return w==A.w?type<A.type:w<A.w;
14     }
15 }a[4005];
16 inline void solve()
17 {
18     sort(a+1,a+n+m+1);
19     for(int i=0;i<=totC;++i)
20         f[i]=-inf;
21     f[0]=0;
22     int tot=0;
23     for(int i=n+m;i>=1;--i)
24         if(a[i].type==0)
25         {
26             int c=a[i].c,v=a[i].v;
27             for(int j=0;j<=tot-c;++j)
28                 f[j]=max(f[j],f[j+c]+v);
29         }
30         else
31         {
32             int c=a[i].c,v=a[i].v;
33             tot+=c;
34             for(int j=tot;j>=c;--j)
35                 f[j]=max(f[j],f[j-c]-v);
36         }
37     ll ans=-inf;
38     for(int i=0;i<=totC;++i)
39         ans=max(ans,f[i]);
40     cout<<ans<<endl;
41 }
42 int main()
43 {
44 //    freopen("a.in","r",stdin);
45 //    ios::sync_with_stdio(false);
46     cin>>n>>m;
47     for(int i=1;i<=n;++i)
48     {
49         cin>>a[i].c>>a[i].w>>a[i].v;
50         totC+=a[i].c;
51         a[i].type=1;
52     }
53     for(int i=n+1;i<=n+m;++i)
54     {
55         cin>>a[i].c>>a[i].w>>a[i].v;
56         a[i].type=0;
57     }
58     solve();
59     return 0;
60 }
View Code

B.将一个数平方后取模很快(24次)就能找到循环节,维护循环节即可。

map是真的慢!!!以后可以认为map、unordered_map的常数是远大于40的。

  1 #include<bits/stdc++.h>
  2 #define mod 998244353
  3 using namespace std;
  4 typedef long long int ll;
  5 const int maxn=2E5+5;
  6 int n,m,tag[maxn*4];
  7 ll a[maxn];
  8 int loop[maxn*4][24],rem[maxn*4],hh[maxn];
  9 bool ok[maxn*4];
 10 inline int read()
 11 {
 12     char ch=getchar();
 13     while(!isdigit(ch))ch=getchar();
 14     int s=ch-'0';ch=getchar();
 15     while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
 16     return s;
 17 }
 18 int G[55];
 19 inline void write(int x)
 20 {
 21     int g=0;
 22     do{G[++g]=x%10;x/=10;}while(x);
 23     for(int i=g;i>=1;--i)putchar('0'+G[i]);putchar('\n');
 24 }
 25 ll tmp[24];
 26 inline void put(int num,int x)
 27 {
 28     tag[num]+=x;
 29     for(int i=0;i<24;++i)
 30         tmp[i]=loop[num][(i+x)%24];
 31     for(int i=0;i<24;++i)
 32         loop[num][i]=tmp[i];
 33     rem[num]=loop[num][0];
 34 }
 35 inline void pushup(int num)
 36 {
 37     ok[num]=ok[num<<1]&ok[num<<1|1];
 38     rem[num]=rem[num<<1]+rem[num<<1|1];
 39     rem[num]-=rem[num]>=mod?mod:0;
 40     if(ok[num])
 41     {
 42         for(int i=0;i<24;++i)
 43             loop[num][i]=loop[num<<1][i]+loop[num<<1|1][i];
 44         for(int i=0;i<24;++i)
 45             loop[num][i]-=loop[num][i]>=mod?mod:0;
 46     }
 47 }
 48 inline void pushdown(int num)
 49 {
 50     int x=tag[num];
 51     if(x==0)
 52         return;
 53     tag[num]=0;
 54     put(num<<1,x),put(num<<1|1,x);
 55 }
 56 void build(int l,int r,int num)
 57 {
 58     if(l==r)
 59     {
 60         hh[l]=24;
 61         rem[num]=a[l];
 62         return;
 63     }
 64     int mid=(l+r)>>1;
 65     build(l,mid,num<<1),build(mid+1,r,num<<1|1);
 66     pushup(num);
 67 }
 68 void change(int L,int R,int l,int r,int num)
 69 {
 70     if(L<=l&&r<=R&&ok[num])
 71     {
 72         put(num,1);
 73         return;
 74     }
 75     if(l==r)
 76     {
 77         a[l]=a[l]*a[l]%mod;
 78         --hh[l];
 79         if(hh[l]==0)
 80         {
 81             ok[num]=1;
 82             ll x=a[l];
 83             for(int i=0;i<24;++i,x=x*x%mod)
 84                 loop[num][i]=x;
 85         }
 86         rem[num]=a[l];
 87         return;
 88     }
 89     pushdown(num);
 90     int mid=(l+r)>>1;
 91     if(R<=mid)
 92         change(L,R,l,mid,num<<1);
 93     else if(mid<L)
 94         change(L,R,mid+1,r,num<<1|1);
 95     else
 96         change(L,R,l,mid,num<<1),change(L,R,mid+1,r,num<<1|1);
 97     pushup(num);
 98 }
 99 ll ask(int L,int R,int l,int r,int num)
100 {
101     if(L<=l&&r<=R)
102         return rem[num];
103     pushdown(num);
104     int mid=(l+r)>>1;
105     if(R<=mid)
106         return ask(L,R,l,mid,num<<1);
107     else if(mid<L)
108         return ask(L,R,mid+1,r,num<<1|1);
109     return ask(L,R,l,mid,num<<1)+ask(L,R,mid+1,r,num<<1|1);
110 }
111 int main()
112 {
113 //    freopen("nagato2.in","r",stdin);
114 //    freopen("a.out","w",stdout);
115     ios::sync_with_stdio(false);
116     n=read(),m=read();
117     for(int i=1;i<=n;++i)
118         a[i]=read();
119     build(1,n,1);
120     while(m--)
121     {
122         int opt=read(),l=read(),r=read();
123         if(opt==1)
124             change(l,r,1,n,1);
125         else
126             write(ask(l,r,1,n,1)%mod);
127     }
128     return 0;
129 }
View Code

 


2020_10_06:

A.找寻环节,模拟即可。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long int ll;
 4 int n,a[605][605];
 5 int tot,wait[605*605];
 6 int vis[605][605];
 7 ll d;
 8 int main()
 9 {
10 //  freopen("speech3.in","r",stdin);
11     ios::sync_with_stdio(false);
12     cin>>n>>d;
13     for(int i=1;i<=n;++i)
14         for(int j=1;j<=n;++j)
15             cin>>a[i][j];
16     int u=1,v=2;
17     for(ll i=1;i<=d;++i)
18     {
19         if(vis[u][v])
20         {
21             int len=i-vis[u][v];
22             ll left=(d-i+1)%len;
23             if(left==0)
24                 cout<<wait[vis[u][v]-1+len]<<endl;
25             else
26                 cout<<wait[vis[u][v]-1+left]<<endl;
27             return 0;
28         }
29         wait[++tot]=u;
30         vis[u][v]=i;
31         int w=a[v][u];
32         u=v;
33         v=w;
34     }
35     cout<<wait[tot]<<endl;
36     return 0;
37 }
View Code

B.

首先,最简单的想法是设f[i][j]表示a序列中到了第i位,b序列中到了第j位的最小代价,简单转移即可。

但发现数据范围实在是太大了,这种情况下通常的想法是找到转移的规律或者是减少状态数。

首先,f[i][j]的第二维可以省略:我们现在a序列和b序列后新增一个很大的数字(n+1),那么我们只需要考虑a[i]在b序列中出现的位置。令f[i]表示考虑a序列到了第i位的最小代价。那么f[i]=min{f[j]+cost(j+1,i)},其中a[j]和a[i]在b序列中是相邻的。cost(l+1,r)可以分两类考虑:一种是a[i]小于0的,显然会直接加在答案里;一种是a[i]大于等于b[j]且大于0的,那么一定也会被加在答案里。前者可以前缀和快速算出,后者可以用树状数组得出。这样的复杂度是O(nlogn)的。

注意到所有数字的值域也是线性的,我们尝试把某些贡献往后移动。具体来说,如果当前决策的数字分别为b[j]和b[i](j<i),那么对于上面的第二种贡献,我们改为统计 大于等于b[j]且小于b[i]且大于0的数字之和,而不考虑它的下标是否在[l,r]中。这显然是对的。具体实现看代码。复杂度为O(n+值域)。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long int ll;
 4 const int maxn=5E6+5;//?!?!?!
 5 const ll inf=1E18;
 6 int n,m,a[maxn],b[maxn],what[maxn],q[maxn];
 7 ll f[maxn],g[maxn],h[maxn],val[maxn];
 8 inline char gc()
 9 {
10     static char now[1<<20],*S,*T;
11     if (T==S)
12     {
13         T=(S=now)+fread(now,1,1<<20,stdin);
14         if (T==S) return EOF;
15     }
16     return *S++;
17 }//getchar
18 inline int read()
19 {
20     int res=0,sign=1;
21     char c;
22     while ((c=gc())<'0'||c>'9') if (c=='-') sign=-1;
23     res=(c^48);
24     while ((c=gc())>='0'&&c<='9') res=(res<<3)+(res<<1)+(c^48);
25     return res*sign;
26 }//read a signed interger
27 int main()
28 {
29 //  freopen("offa6.in","r",stdin);
30     n=read();
31     for(int i=1;i<=n;++i)
32         a[i]=read();
33     for(int i=1;i<=n;++i)
34         val[i]=read();
35     m=read();
36     for(int i=1;i<=m;++i)
37     {
38         b[i]=read();
39         what[b[i]]=i;
40     }
41     n+=1,m+=1;
42     a[n]=n,b[m]=n;
43     what[n]=m;
44     for(int i=0;i<=m;++i)
45         g[i]=inf;
46     ll now=inf,x=0;
47     g[0]=0;
48     for(int i=1,j=1;i<=n;q[i++]=j)
49         if(b[j]<i)
50             ++j;
51     for(int i=1;i<=n;++i)
52     {
53         int pos=what[a[i]];
54         if(pos)
55             f[i]=(g[pos-1]<now)?g[pos-1]+h[pos]+x:now;
56         if(val[i]>=0)
57             h[q[a[i]]]+=val[i];
58         else
59             x+=val[i];
60         if(pos&&f[i]<now)
61             g[pos]=min(g[pos],f[i]-x);
62     }
63     if(f[n]<now)
64         cout<<f[n]<<endl;
65     else
66         cout<<"Impossible"<<endl;
67     return 0;
68 }
View Code

C.

首先计算出从节点u经过一条边走到节点v的期望时间,那么对于一条路径,时间为经过的路径的权值之和。这个要么推式子,要么感性理解,要么打表找规律。

以1为根后,一条路径的权值为((u->1)+(1->v)-(lca(u,v)->1+1->lca(u,v)))。m次方需要记录一个子树中的0~m次方的分别的和。想怎么算就怎么算。

要优化当然上ntt了。

  1 #include<bits/stdc++.h>
  2 #define mod 998244353
  3 using namespace std;
  4 typedef long long int ll;
  5 const int maxn=3E4+5;
  6 int n,m;
  7 int size,head[maxn];
  8 ll up[maxn],down[maxn],sum[maxn],C[51][51];
  9 ll f[maxn][51],g[maxn][51];
 10 struct edge
 11 {
 12     int to,next;
 13 }E[maxn*2];
 14 inline void add(int u,int v)
 15 {
 16     E[++size].to=v;
 17     E[size].next=head[u];
 18     head[u]=size;
 19 }
 20 inline ll qpow(ll x,ll y)
 21 {
 22     ll ans=1,base=x;
 23     while(y)
 24     {
 25         if(y&1)
 26             ans=ans*base%mod;
 27         base=base*base%mod;
 28         y>>=1;
 29     }
 30     return ans;
 31 }
 32 inline void init()
 33 {
 34     C[0][0]=1;
 35     for(int i=1;i<=50;++i)
 36     {
 37         C[i][0]=1;
 38         for(int j=1;j<=i;++j)
 39             C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
 40     }
 41 }
 42 void dfs1(int u,int F)
 43 {
 44     down[u]=0;
 45     ll s=0;
 46     sum[u]=1;
 47     for(int i=head[u];i;i=E[i].next)
 48     {
 49         int v=E[i].to;
 50         if(v==F)
 51             continue;
 52         dfs1(v,u);
 53         sum[u]+=sum[v];
 54         s+=up[v]+1;
 55     }
 56     up[u]=(s+1)%mod;
 57 }
 58 ll ans;
 59 void dfs2(int u,int F,ll d1,ll d2,ll d3)
 60 {
 61     d1=(d1+up[u])%mod;
 62     d3=(d2+d3)%mod;
 63     up[u]=d1;
 64     down[u]=d3;
 65     ll s=1+d2;
 66     if(F==0)
 67         s-=1;
 68     for(int i=head[u];i;i=E[i].next)
 69     {
 70         int v=E[i].to;
 71         if(v==F)
 72             continue;
 73         s+=1+up[v];
 74     }
 75     for(int i=head[u];i;i=E[i].next)
 76     {
 77         int v=E[i].to;
 78         if(v==F)
 79             continue;
 80         dfs2(v,u,d1,(s-up[v]+mod)%mod,d3);
 81     }
 82 }
 83 void dfs3(int u,int F)
 84 {
 85     ll tmp[51];
 86     tmp[0]=1;
 87     for(int i=1;i<=m;++i)
 88         tmp[i]=-tmp[i-1]*(up[u]+down[u])%mod;
 89     for(int i=0;i<=m;++i)
 90         f[u][i]=qpow(up[u],i),g[u][i]=qpow(down[u],i);
 91     for(int e=head[u];e;e=E[e].next)
 92     {
 93         int v=E[e].to;
 94         if(v==F)
 95             continue;
 96         dfs3(v,u);
 97         for(int i=0;i<=m;++i)
 98             for(int j=0;j<=i;++j)
 99             {
100                 ans=(ans+C[m][i]*C[i][j]%mod*tmp[m-i]%mod*f[u][j]%mod*g[v][i-j]%mod)%mod;
101                 ans=(ans+C[m][i]*C[i][j]%mod*tmp[m-i]%mod*g[u][j]%mod*f[v][i-j]%mod)%mod;
102             }
103         for(int i=0;i<=m;++i)
104             f[u][i]=(f[u][i]+f[v][i])%mod,g[u][i]=(g[u][i]+g[v][i])%mod;
105     }
106 }
107 int main()
108 {
109 //    freopen("dream6.in","r",stdin);
110     ios::sync_with_stdio(false);
111     cin>>n>>m;
112     init();
113     for(int i=2;i<=n;++i)
114     {
115         int x,y;
116         cin>>x>>y;
117         add(x,y);
118         add(y,x);
119     }
120     dfs1(1,0);
121     dfs2(1,0,-up[1],0,0);
122     dfs3(1,0);
123     cout<<(ans%mod+mod)%mod<<endl;
124     return 0;
125 }
View Code

 


 2020_10_07:

A.对于一个权值,记录所有可能到达的位置。bitset优化。但我却手写了一个bitset(因为用了错误的复杂度)。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 int n,m,d;
  4 const int LEN=32768;
  5 int OUT,tmp[LEN];
  6 struct Bitset
  7 {
  8     unsigned a[LEN];
  9     void reset(){memset(a,0,sizeof(unsigned)*min(OUT,LEN));}
 10     Bitset(){reset();}
 11     void set(int x){a[x>>5]|=1<<(x&31);}
 12     void reset(int x){a[x>>5]&=~(1<<(x&31));}
 13     void operator |=(Bitset &b)
 14     {
 15         int up=min(LEN,OUT);
 16         for(int i=0;i<up;i++)a[i]=a[i]|b.a[i];
 17     }
 18     void operator <<=(const int t)
 19     {
 20         unsigned last=0;
 21         int high=t>>5,low=t&31;
 22         int up=min(LEN,OUT);
 23         for(int i=0;i<up;++i)
 24             tmp[i]=0;
 25         if(low)
 26             for(int i=0;i+high<up;i++)
 27             {
 28                 tmp[i+high]=last|(a[i]<<low);
 29                 last=a[i]>>(32-low);
 30             }
 31         else
 32             for(int i=0;i+high<up;i++)
 33                 tmp[i+high]=last|(a[i]<<low);
 34         for(int i=0;i<up;++i)
 35             a[i]=tmp[i];
 36     }
 37     inline int count()
 38     {
 39         int s=0;
 40         for(int i=0;i<LEN;++i)
 41             s+=__builtin_popcount(a[i]);
 42         return s;
 43     }
 44 };
 45 Bitset have[95],g[95],ans;
 46 int size,head[95];
 47 struct edge
 48 {
 49     int to,next,w;
 50 }E[55555];
 51 inline void add(int u,int v,int w)
 52 {
 53     E[++size].to=v;
 54     E[size].next=head[u];
 55     E[size].w=w;
 56     head[u]=size;
 57 }
 58 inline void get(int bias)
 59 {
 60     if(bias==0)
 61     {
 62         for(int u=1;u<=n;++u)
 63             for(int i=head[u];i;i=E[i].next)
 64             {
 65                 int v=E[i].to,w=E[i].w;
 66                 if(v==1)
 67                     have[u].set(w);
 68             }
 69         return;
 70     }
 71     OUT=2*bias;
 72 //  cout<<"? "<<OUT<<endl;
 73     for(int u=1;u<=n;++u)
 74     {
 75         g[u].reset();
 76         for(int i=head[u];i;i=E[i].next)
 77         {
 78             int v=E[i].to,w=E[i].w;
 79             if(!w)
 80                 g[u]|=have[v];
 81         }
 82         g[u]<<=bias;
 83         for(int i=head[u];i;i=E[i].next)
 84         {
 85             int v=E[i].to,w=E[i].w;
 86             if(w)
 87                 g[u]|=have[v];
 88         }
 89     }
 90     for(int u=1;u<=n;++u)
 91         have[u]=g[u];
 92 }
 93 int main()
 94 {
 95 //  freopen("a.in","r",stdin);
 96     ios::sync_with_stdio(false);
 97     cin>>n>>m>>d;
 98 //  n=90,m=90*89,d=20;
 99     for(int i=1;i<=m;++i)
100     {
101         int x,y,z;
102         cin>>x>>y>>z;
103         add(x,y,z);
104         add(y,x,z);
105     }
106     /*
107     for(int i=1;i<=n;++i)
108         for(int j=i+1;j<=n;++j)
109         {
110             int x=i,y=j,z=rand()%2;
111             add(x,y,z);
112             add(y,x,z);
113             add(x,y,z);
114             add(y,x,z);
115         }
116         */
117     get(0);
118     for(int i=1;i<d;++i)
119         get(1<<i);
120     OUT=LEN;
121     for(int i=1;i<=n;++i)
122         ans|=have[i];
123     cout<<ans.count()<<endl;
124     return 0;
125 }
View Code

B.

不妨反过来考虑(同时,你的私家车显然不能停在其他人的车上,但数据竟然有这种情况!)。答案首先是单调增的,如果答案会改变,那么这个正方形一定会包含刚刚消去的位置。显然用单调队列判断即可。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=2005;
  4 int n,m,k,ans[maxn];
  5 int U[maxn][maxn],D[maxn][maxn],L[maxn][maxn],f[maxn][maxn];
  6 int a[maxn][maxn];
  7 struct pt
  8 {
  9     int x,y;
 10 }b[maxn];
 11 inline void init()
 12 {
 13     for(int i=1;i<=n;++i)
 14         for(int j=1;j<=m;++j)
 15             if(!a[i][j])
 16             {
 17                 L[i][j]=L[i][j-1]+1;
 18                 U[i][j]=U[i-1][j]+1;
 19                 f[i][j]=min(min(L[i][j],U[i][j]),f[i-1][j-1]+1);
 20                 ans[k]=max(ans[k],f[i][j]);
 21             }
 22     for(int j=1;j<=m;++j)
 23         for(int i=n;i>=1;--i)
 24             D[i][j]=a[i][j]?0:D[i+1][j]+1;
 25 }
 26 inline void clear(int x,int y)
 27 {
 28     --a[x][y];
 29     for(int i=1;i<=n;++i)
 30         U[i][y]=a[i][y]?0:U[i-1][y]+1;
 31     for(int i=n;i>=1;--i)
 32         D[i][y]=a[i][y]?0:D[i+1][y]+1;
 33 }
 34 int q[maxn],tmp1[maxn],tmp2[maxn];
 35 inline bool ok(int len,int x,int y)
 36 {
 37     if(len>n||len>m)
 38         return false;
 39     int l=max(1,y-len+1),r=min(m,y+len-1);
 40     int tot1=0,tot2=0,head=1,tail=0;
 41     for(int i=l;i<=r;++i)
 42     {
 43         while(head<=tail&&i-q[head]==len)
 44             ++head;
 45         while(head<=tail&&U[x][i]<=U[x][q[tail]])
 46             --tail;
 47         q[++tail]=i;
 48         if(i-l+1>=len)
 49             tmp1[++tot1]=U[x][q[head]];
 50     }
 51     head=1,tail=0;
 52     for(int i=l;i<=r;++i)
 53     {
 54         while(head<=tail&&i-q[head]==len)
 55             ++head;
 56         while(head<=tail&&D[x][i]<=D[x][q[tail]])
 57             --tail;
 58         q[++tail]=i;
 59         if(i-l+1>=len)
 60             tmp2[++tot2]=D[x][q[head]];
 61     }
 62 //  cout<<"H "<<tot1<<endl;
 63 //  for(int i=1;i<=tot1;++i)
 64 //      cout<<tmp1[i]<<" "<<tmp2[i]<<endl;
 65     for(int i=1;i<=tot1;++i)
 66         if(tmp1[i]+tmp2[i]-1>=len)
 67             return true;
 68     return false;
 69 }
 70 int main()
 71 {
 72 //  freopen("a.in","r",stdin);
 73     ios::sync_with_stdio(false);
 74     cin>>n>>m>>k;
 75     for(int i=1;i<=n;++i)
 76     {
 77         string str;
 78         cin>>str;
 79         for(int j=1;j<=m;++j)
 80             if(str[j-1]=='X')
 81                 a[i][j]=1;
 82     }
 83     for(int i=1;i<=k;++i)
 84     {
 85         cin>>b[i].x>>b[i].y;
 86         ++a[b[i].x][b[i].y];
 87     }
 88     init();
 89     int pos=ans[k];
 90     for(int i=k;i>1;--i)
 91     {
 92         clear(b[i].x,b[i].y);
 93         while(ok(pos+1,b[i].x,b[i].y))
 94             ++pos;
 95         ans[i-1]=pos;
 96     }
 97     for(int i=1;i<=k;++i)
 98         cout<<ans[i]<<'\n';
 99     return 0;
100 }
View Code

C.

$mu_n^2=\sum_{d^2|n}{mu_d}$

 1 #include<bits/stdc++.h>
 2 #define mod 1000000007
 3 using namespace std;
 4 typedef long long int ll;
 5 const int maxn=1E6+5;
 6 const int limit=1000000;
 7 int size,prime[maxn],have[maxn],mu[maxn];
 8 bool vis[maxn];
 9 ll n;
10 inline void init()
11 {
12     for(int i=2;i<=limit;++i)
13     {
14         if(!vis[i])
15             prime[++size]=i,have[i]=1,mu[i]=-1;
16         for(int j=1;j<=size&&prime[j]*i<=limit;++j)
17         {
18             int num=prime[j]*i;
19             vis[num]=1;
20             have[num]=have[i];
21             if(i%prime[j]==0)
22                 break;
23             ++have[num];
24             mu[num]=-mu[i];
25         }
26     }
27     mu[1]=1;
28 }
29 inline ll f(int x)
30 {
31     return have[x];
32 }
33 inline void solve()
34 {
35     ll s=0,up=sqrt(n);
36     for(int k=1;k<=up;++k)
37     {
38         if(!mu[k])
39             continue;
40         ll g=0,d=n/k/k;
41         ll sd=sqrt(d);
42         for(int l=1;l<=sd;++l)
43             g=(g+d/l)%mod;
44         g=(g*2-sd*sd%mod+mod)%mod*mu[k]%mod;
45         s=(s+g)%mod;
46     }
47     cout<<(s%mod+mod)%mod<<endl;
48 }
49 int main()
50 {
51     ios::sync_with_stdio(false);
52     init();
53     cin>>n;
54     solve();
55     return 0;
56 }
View Code

 


 

2020_10_08:

A.CF717F

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long int ll;
 4 const int maxn=1005;
 5 int n,m;
 6 ll a[maxn],f[maxn][maxn],tmp[maxn];
 7 inline void solve()
 8 {
 9     ll q;
10     cin>>q;
11     int pos=upper_bound(tmp,tmp+n+1,q)-tmp;
12     cout<<n-pos+1<<endl;
13 }
14 int main()
15 {
16     ios::sync_with_stdio(false);
17     cin>>n>>m;
18     for(int i=1;i<=n;++i)
19         cin>>a[i];
20     reverse(a+1,a+n+1);
21     for(int i=1;i<=n;++i)
22     {
23         for(int j=1;j<=i;++j)
24             f[i][j]=min(max(f[i-1][j]-a[i],(ll)0),f[i-1][j-1]);
25         //it will be impossible if the initial value is minus !!!
26         f[i][0]=max(f[i-1][0]-a[i],(ll)0);
27     }
28     for(int i=0;i<=n;++i)
29         tmp[i]=f[n][n-i];
30     while(m--)
31         solve();
32     return 0;
33 }
View Code

B.

1.用线性gcd。

2.没有平方因子的性质:设f(n,m)为$\sum_{i=1}^{m}{phi(i*n)}$,若p|n(n没有平方因子),那么f(n,m)=(p-1)*f(n/p,m)+f(n,m/p)。把它拆成有p因子的贡献和没有p因子的贡献,然后推式子(但我不能感性理解)。

3.单测,线筛啊。

4.数据太水了,gcd的log过去了。

 1 #include<bits/stdc++.h>
 2 #define MOD 1000000007
 3 using namespace std;
 4 typedef long long int ll;
 5 const int maxn=1E7+5;
 6 const int limit=10000000;
 7 int size,prime[maxn],phi[maxn],sum[maxn];
 8 int tot,tmp[555];
 9 bool vis[maxn];
10 //IMPLAUSIABLE TO MERGE THESE TWO QUIZ !!!
11 inline ll qpow(ll x,ll y,ll mod)
12 {
13     ll ans=1,base=x;
14     while(y)
15     {
16         if(y&1)
17             ans=ans*base%mod;
18         base=base*base%mod;
19         y>>=1;
20     }
21     return ans%mod;
22 }
23 inline void init()
24 {
25     for(int i=2;i<=limit;++i)
26     {
27         if(!vis[i])
28             prime[++size]=i,phi[i]=i-1;
29         for(int j=1;j<=size&&prime[j]*i<=limit;++j)
30         {
31             int num=prime[j]*i;
32             vis[num]=1;
33             if(i%prime[j]==0)
34             {
35                 phi[num]=phi[i]*prime[j];
36                 break;
37             }
38             phi[num]=phi[i]*(prime[j]-1);
39         }
40     }
41     phi[1]=1;
42     for(int i=1;i<=limit;++i)
43         sum[i]=(sum[i-1]+phi[i])%MOD;
44 }
45 ll fuckyou(ll k,ll mod)
46 {
47     if(mod==1)
48         return 0;
49     ll x=fuckyou(k,phi[mod]);
50     return qpow(k,x+phi[mod],mod);
51 }
52 map<int,map<int,ll> >G;
53 ll get(int n,int m)
54 {
55     if(G[n][m])
56         return G[n][m];
57     if(m==0)
58         return 0;
59     if(n==1)
60         return sum[m];
61     if(m==1)
62         return phi[n];
63     for(int i=1;i<=tot;++i)
64     {
65         int x=tmp[i];
66         if(n%x==0)
67             return G[n][m]=(get(n/x,m)*phi[x]%MOD+get(n,m/x))%MOD;
68     }
69     assert(0);
70     return 0;
71 }
72 int main()
73 {
74     ios::sync_with_stdio(false);
75     init();
76     ll n,m,p;
77     cin>>n>>m>>p;
78     ll g=n;
79     for(int i=2;i<=n;++i)
80         if(n%i==0)
81         {
82             tmp[++tot]=i;
83             n/=i;
84         }
85     if(n>=2)
86         tmp[++tot]=n;
87     cout<<fuckyou(get(g,m),p)<<endl;
88     return 0;
89 }
View Code

C.51nod1355

 1 #include<bits/stdc++.h>
 2 #define mod 1000000007
 3 using namespace std;
 4 typedef long long int ll;
 5 ll n,f[1000005],g[1000005],ans=1;
 6 bool vis[1000005];
 7 inline ll qpow(ll x,ll y)
 8 {
 9     ll ans=1,base=x;
10     while(y)
11     {
12         if(y&1)
13             ans=ans*base%mod;
14         base=base*base%mod;
15         y>>=1;
16     }
17     return ans;
18 }
19 void init()
20 {
21     g[1]=f[1]=1;
22     for(int i=2;i<=1000000;++i)
23         g[i]=f[i]=(f[i-1]+f[i-2])%mod;
24     for(int i=2;i<=1000000;++i)
25     {
26         ll x=qpow(g[i],mod-2);
27         for(int j=2;j*i<=1000000;++j)
28             g[j*i]=g[j*i]*x%mod;
29     }
30 }
31 int main()
32 {
33     ios::sync_with_stdio(false);
34     init();
35     cin>>n;
36     for(int i=1;i<=n;++i)
37     {
38         int x;
39         cin>>x;
40         vis[x]=1;
41     }
42     for(int i=1;i<=1000000;++i)
43         for(int j=1;j*i<=1000000;++j)
44             if(vis[j*i])
45             {
46                 ans=ans*g[i]%mod;
47                 break;
48             }
49     cout<<ans<<endl;
50     return 0;
51 }
View Code

 

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