XJOI网上同步训练DAY3 T1

思路:看来我真是思博了,这么简单的题目居然没想到,而且我对复杂度的判定也有点问题。。

首先我们选了一个位置i的b,那一定只对i和以后的位置造成改变,因此我们可以这样看:

我们从前往后选,发现一个位置的s和r相等,然后我们就选这个位置的bi,由于bi会改变当前位置,因此当前位置的vi我们就能吃到了。所以,每个位置的vi我们都能拿到,所以答案就是Σvi,然后只要模拟过去就可以了。。

我真是太弱鸡了。。还有这个算法的复杂度是O(N^1.5),我一直以为是O(N^2)。。

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cstring>
 6 #define ll long long
 7 ll sum,r[200005],s[200005];
 8 int n,b[200005],v[200005],ans[200005],d[200005];
 9 ll read(){
10     ll t=0,f=1;char ch=getchar();
11     while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
12     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
13     return t*f;
14 }
15 int main(){
16     n=read();
17     for (int i=1;i<=n;i++) b[i]=read();
18     for (int i=1;i<=n;i++) r[i]=read();
19     for (int i=1;i<=n;i++) v[i]=read(),sum+=v[i];
20     for (int i=1;i<=n;i++)
21      for (int j=i;j<=n;j+=i)
22       d[j]++;
23     for (int i=1;i<=n;i++)
24      if (s[i]==r[i])  {
25             ans[i]=1;
26             for (int j=n/i;j>=1;j--)
27              s[i*j]+=(ll)b[i]*d[j];
28      }
29     printf("%lld
",sum);
30     for (int i=1;i<=n;i++) printf("%d ",ans[i]); 
31 }
原文地址:https://www.cnblogs.com/qzqzgfy/p/5620112.html