Codeforces Round #572 (Div. 2)

 

C - Candies!

有助于理解倍增,ST算法

dp

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <string>
 6 #include <algorithm>
 7 #include <iostream>
 8 using namespace std;
 9 #define ll long long
10 
11 const double eps=1e-8;
12 const ll inf=1e9;
13 const ll mod=1e9+7;
14 const int maxn=1e5+10;
15 
16 int a[maxn],f[20][maxn],candy[20][maxn];
17 
18 int main()
19 {
20     int n,q,i,j,k,l,nn,x,y;
21     scanf("%d",&n);
22     for (i=1;i<=n;i++)
23         scanf("%d",&f[0][i]);
24 
25     nn=log(n+eps)/log(2);
26     for (j=1;j<=nn;j++)
27     {
28         k=n-(1<<j)+1;
29         l=(1<<(j-1));
30         for (i=1;i<=k;i++)
31         {
32             f[j][i]=(f[j-1][i]+f[j-1][i+l])%10;
33             candy[j][i]=candy[j-1][i]+candy[j-1][i+l]+(f[j-1][i]+f[j-1][i+l]>=10);
34         }
35     }
36 
37     scanf("%d",&q);
38     while (q--)
39     {
40         scanf("%d%d",&x,&y);
41         nn=log(y-x+1+eps)/log(2);
42         printf("%d\n",candy[nn][x]);
43     }
44     return 0;
45 }

 

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <string>
 6 #include <algorithm>
 7 #include <iostream>
 8 using namespace std;
 9 #define ll long long
10  
11 const double eps=1e-8;
12 const ll inf=1e9;
13 const ll mod=1e9+7;
14 const int maxn=1e5+10;
15  
16 int tot[maxn],candy[20][maxn];
17  
18 int main()
19 {
20     int n,q,i,j,k,l,m,nn,x,y,a;
21     scanf("%d",&n);
22     for (i=1;i<=n;i++)
23     {
24         scanf("%d",&a);
25         tot[i]=(tot[i-1]+a)%10;
26     }
27  
28     nn=log(n+eps)/log(2);
29     for (j=1;j<=nn;j++)
30     {
31         k=n-(1<<j)+1;
32         l=(1<<(j-1));
33         m=(1<<j);
34         for (i=1;i<=k;i++)
35             candy[j][i]=candy[j-1][i]+candy[j-1][i+l]+( (tot[i+m-1]-tot[i+l-1]+10)%10 + (tot[i+l-1]-tot[i-1]+10)%10 >= 10 );
36     }
37  
38     scanf("%d",&q);
39     while (q--)
40     {
41         scanf("%d%d",&x,&y);
42         nn=log(y-x+1+eps)/log(2);
43         printf("%d\n",candy[nn][x]);
44     }
45     return 0;
46 }
47  

 

E - Count Pairs

好好学习数学。。。

 

#define mul(x,y) (ll)x*y%p
优点:

1.  宏定义,在编译为汇编代码时,减少执行次数(国家集训队有一篇文章),运行时间减少
2. 不容易漏写
实测:156ms -> 140ms

 

学习其它代码:

 

数组统计不同相同数字的个数

三种写法

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <string>
 6 #include <algorithm>
 7 #include <iostream>
 8 using namespace std;
 9 #define ll long long
10 #define mul(x,y) (ll)x*y%p
11  
12 const double eps=1e-8;
13 const ll inf=1e9;
14 const ll mod=1e9+7;
15 const int maxn=3e5+10;
16  
17 ll a[maxn];
18  
19 int main()
20 {
21     ll n,p,k,i,j,sum=0;
22     scanf("%lld%lld%lld",&n,&p,&k);
23     for (i=1;i<=n;i++)
24     {
25         scanf("%lld",&j);
26         a[i]=(mul(mul(mul(j,j),j),j)-mul(k,j)+p)%p;
27     }
28     sort(a+1,a+n+1);
29     a[n+1]=-1;
30     j=1;
31     for (i=1;i<=n;i++)
32         if (a[i]!=a[i+1])
33         {
34             sum+=(i-j+1)*(i-j)/2;
35             j=i+1;
36         }
37     printf("%lld",sum);
38     return 0;
39 }

 

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <string>
 6 #include <algorithm>
 7 #include <iostream>
 8 using namespace std;
 9 #define ll long long
10 #define mul(x,y) (ll)x*y%p
11  
12 const double eps=1e-8;
13 const ll inf=1e9;
14 const ll mod=1e9+7;
15 const int maxn=3e5+10;
16  
17 ll a[maxn];
18  
19 int main()
20 {
21     ll n,p,k,i,j,sum=0;
22     scanf("%lld%lld%lld",&n,&p,&k);
23     for (i=1;i<=n;i++)
24     {
25         scanf("%lld",&j);
26         a[i]=(mul(mul(mul(j,j),j),j)-mul(k,j)+p)%p;
27     }
28     sort(a+1,a+n+1);
29     a[n+1]=-1;
30     for (i=1;i<=n;i++)
31     {
32         j=i;
33         while (a[i]==a[i+1])
34             i++;
35         sum+=(i-j+1)*(i-j)/2;
36     }
37     printf("%lld",sum);
38     return 0;
39 }
40  

 

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <string>
 6 #include <algorithm>
 7 #include <iostream>
 8 using namespace std;
 9 #define ll long long
10 #define mul(x,y) (ll)x*y%p
11  
12 const double eps=1e-8;
13 const ll inf=1e9;
14 const ll mod=1e9+7;
15 const int maxn=3e5+10;
16  
17 ll a[maxn];
18  
19 int main()
20 {
21     ll n,p,k,i,j,sum=0,cnt;
22     scanf("%lld%lld%lld",&n,&p,&k);
23     for (i=1;i<=n;i++)
24     {
25         scanf("%lld",&j);
26         a[i]=(mul(mul(mul(j,j),j),j)-mul(k,j)+p)%p;
27     }
28     sort(a+1,a+n+1);
29  
30     cnt=1;
31     for (i=1;i<n;i++)
32         if (a[i]==a[i+1])
33             cnt++;
34         else
35             sum+=cnt*(cnt-1)/2,cnt=1;
36     sum+=cnt*(cnt-1)/2;
37     printf("%lld",sum);
38     return 0;
39 }
40  

 

末尾加上不同元素 or 添加末尾的处理/特判

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <string>
 6 #include <algorithm>
 7 #include <iostream>
 8 using namespace std;
 9 #define ll long long
10 #define mul(x,y) (ll)x*y%p
11  
12 const double eps=1e-8;
13 const ll inf=1e9;
14 const ll mod=1e9+7;
15 const int maxn=3e5+10;
16  
17 ll a[maxn];
18  
19 int main()
20 {
21     ll n,p,k,i,j,sum=0;
22     scanf("%lld%lld%lld",&n,&p,&k);
23     for (i=1;i<=n;i++)
24     {
25         scanf("%lld",&j);
26         a[i]=(mul(mul(mul(j,j),j),j)-mul(k,j)+p)%p;
27     }
28     sort(a+1,a+n+1);
29     for (i=1;i<=n;i++)
30     {
31         j=i;
32         while (i!=n && a[i]==a[i+1])
33             i++;
34         sum+=(i-j+1)*(i-j)/2;
35     }
36     printf("%lld",sum);
37     return 0;
38 }
39  

 

 

用map

容易写,相应地运行时间增加

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
#define ll long long
#include <map>
#define mul(x,y) (ll)x*y%p
 
const double eps=1e-8;
const ll inf=1e9;
const ll mod=1e9+7;
const int maxn=3e5+10;
 
map<int,int> ma;
 
int main()
{
    ll n,p,k,i,j,sum=0;
    scanf("%lld%lld%lld",&n,&p,&k);
    for (i=1;i<=n;i++)
    {
        scanf("%lld",&j);
        ma[ (mul(mul(mul(j,j),j),j)-mul(k,j)+p)%p ]++;
    }
 
    for (auto l:ma)
        sum+=l.second*(l.second-1)/2;
 
    printf("%lld",sum);
    return 0;
}
 

 

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <string>
 6 #include <algorithm>
 7 #include <iostream>
 8 using namespace std;
 9 #define ll long long
10 #include <map>
11 #define mul(x,y) (ll)x*y%p
12  
13 const double eps=1e-8;
14 const ll inf=1e9;
15 const ll mod=1e9+7;
16 const int maxn=3e5+10;
17  
18 map<int,int> ma;
19  
20 int main()
21 {
22     ll n,p,k,i,j,sum=0;
23     scanf("%lld%lld%lld",&n,&p,&k);
24     for (i=1;i<=n;i++)
25     {
26         scanf("%lld",&j);
27         ma[ (mul(mul(mul(j,j),j),j)-mul(k,j)+p)%p ]++;
28     }
29  
30     for (pair<int,int> l:ma)
31         sum+=l.second*(l.second-1)/2;
32  
33     printf("%lld",sum);
34     return 0;
35 }

 

一个脑洞:

同一个数字c有x个 x^2-x

y=a*x^2+b*x+c

对于二次函数,对于每次数字c的个数的改变,加上a

1+...+x=x^2+x

0+...+x-1=x^2-x

 

如 tot[c]++,sum+=tot[c]*a,

sum+=(b-a)*tot[c]+c。

 

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <string>
 6 #include <algorithm>
 7 #include <iostream>
 8 using namespace std;
 9 #define ll long long
10 #define mul(x,y) (ll)x*y%p
11 #include <map>
12  
13 const double eps=1e-8;
14 const ll inf=1e9;
15 const ll mod=1e9+7;
16 const int maxn=3e5+10;
17  
18 map<ll,ll> ma;
19  
20 int main()
21 {
22     ll n,p,k,i,j,v,sum=0;
23     scanf("%lld%lld%lld",&n,&p,&k);
24     for (i=1;i<=n;i++)
25     {
26         scanf("%lld",&j);
27         v=(mul(mul(mul(j,j),j),j)-mul(k,j)+p)%p;
28         sum+=ma[v]++;///二次函数都可以这样写
29         ///每次获取ma[v]都需要时间,时间开销较大,如果是数组,则这个方法既便捷,运行时间也不会多多少
30     }
31     printf("%lld",sum);
32     return 0;
33 }
34  

 

posted @ 2019-07-06 12:29  congmingyige  阅读(287)  评论(0编辑  收藏  举报