标签:两个指针 ace href 指针 clu ret int name tps
https://codeforces.com/contest/1372
众所周知,\(1+1\neq 1\)。
所以输出 \(n\) 个 \(1\) 即可。
时间复杂度 \(O(tn)\)。
#include <bits/stdc++.h>
using namespace std;
int t;
int n;
int main() {
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
for(int i=1;i<=n;i++)
printf("1 ");
puts("");
}
return 0;
}
设 \(x\) 为 \(n\) 最小的质因数。
此时答案为 \(\frac{n}{x},n-\frac{n}{x}\)。
于是可以 \(O(\sqrt{n})\) 解决每组数据。
#include <bits/stdc++.h>
using namespace std;
int t;
int n,fl;
int main() {
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
fl=1;
for(int i=2;i*i<=n;i++)
if(n%i==0) {
printf("%d %d\n",n/i,n-n/i);
fl=0;
break;
}
if(fl)
printf("%d %d\n",1,n-1);
}
return 0;
}
考虑将每个数按在不在自己的位置归类。
找到所有不在自己的位置的段的个数即可。
于是您就 WA 了。
如果有若干段不在自己的位置的段的话,可以考虑把所有位置全部打乱,再一一对应。
时间复杂度:\(O(tn)\)。
#include <bits/stdc++.h>
using namespace std;
int t;
int n,a[200010],fl;
long long ans;
int main() {
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
ans=0;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=2;i<=n;i++)
if(a[i]==i&&a[i-1]!=i-1)
ans++;
if(a[n]!=n)
ans++;
if(ans>2)
ans=2;
printf("%d\n",ans);
}
return 0;
}
这个出题人我点个赞!
看到环形,就能想到破环为链,先破掉。
然后呢?
找规律 txdy!
捏组样例看看:
1 2 3 4 5 6 7
(2+7) 3 4 5 6 // 对 1 处进行操作
3 4 (5+2+7) // 对 6 处进行操作
3+5+2+7 //对 4 处进行操作
考虑对答案的贡献的数,似乎没规律的样子。
可是一条链的视角来看呢?
1 2 (3) 4 (5) 6 (7) 1 (2) 3 4 5 6 7
可以猜测,对于任意的环而言,均有这样的规律。
所以,我们可以求出下标均为奇数,长度为 \(\frac{n+1}{2}\) 的连续子序列。
对偶数也一样。
求连续子序列的和可以使用 \(l,r\) 两个指针。
时间复杂度 \(O(n)\)。
#include <bits/stdc++.h>
using namespace std;
int t,l,r;
int n,a[400010],k;
long long ans,sum;
int main() {
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
a[i+n]=a[i];
k=(n+1)/2-1;
l=1,r=l+k*2;
for(int i=l;i<=r;i+=2)
sum+=a[i];
ans=max(ans,sum);
while(r<=2*n) {
l+=2,r+=2;
sum-=a[l-2];
sum+=a[r];
ans=max(ans,sum);
}
l=2,r=l+k*2;
sum=0;
for(int i=l;i<=r;i+=2)
sum+=a[i];
ans=max(ans,sum);
while(r<=2*n) {
l+=2,r+=2;
sum-=a[l-2];
sum+=a[r];
ans=max(ans,sum);
}
printf("%lld\n",ans);
return 0;
}
标签:两个指针 ace href 指针 clu ret int name tps
原文地址:https://www.cnblogs.com/lajiccf/p/CF655.html