思路:看来我真是思博了,这么简单的题目居然没想到,而且我对复杂度的判定也有点问题。。
首先我们选了一个位置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 }