暴力枚举即可,对于条件12,可以用l,r记录保存,条件3用数组存储
计算长度并去重即可。答案肯定大于等于0.
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
ll a[N],b[N];
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
int l=-1e9,r=1e9;
vector<int>c;
for(int i=0;i<n;i++) {
int x,y;
cin>>x;
if(x==1){
cin>>y;
l=max(l,y);
}
else if(x==2) {
cin>>y;
r=min(r,y);
}
else {
cin>>y;
c.push_back(y);
}
}
sort(c.begin(),c.end());
unique(c.begin(),c.end());
int res=r-l+1;
for(int i=0;i<c.size();i++){
if(c[i]<=r&&c[i]>=l) res--;
}
cout<<max(res,0)<<endl;
}
}
排序+贪心+滑动窗口
首先要把滑动窗口内的值算出来,一边进,一边出,计算出总数
用总数减去二倍滑动窗口内的值取最大值。
如果删除次数大于元素个数,那么答案肯定大于0,
如果最后还有次数没用,可以将窗口内的删除
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
ll a[N],b[N];
int main(){
int t;
cin>>t;
while(t--){
int n,m,k;
cin>>n>>m>>k;
ll sum=0;
for(int i=0;i<n;i++) cin>>a[i],sum+=a[i];
sort(a,a+n);
ll s=0;
ll res=-1e9;
for(int i=n-1;i>=n-k;i--){
s+=a[i];
}
// cout<<s;
int cnt=m;
res=max(res,sum-2*s);
for(int i=n-k-1;i>=max(n-k-m,0);i--){
s+=a[i];
s-=a[i+k];
sum-=a[i+k];
// cout<<sum<<" "<<s<<endl;
res=max(res,sum-2*s);
cnt--;
}
if(cnt>0){
for(int i=k-1;i>=max(0,k-cnt);i--){
s-=a[i];
sum-=a[i];
res=max(res,sum-2*s);
}
}
if(m>=n) res=max(res,0ll);
cout<<res<<endl;
}
}
枚举最大公约数
a[i]%m a[j]%m相同的话
区间k为n因数
m要成为每个区间对应数的约数并且不为1,使a[i],a[i+1*k],a[i,i+2*k]相同。
复杂度大概是nlogn*因子数目
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
ll a[N],b[N];
int gcd(int a,int b){
if(b==0) return a;
return gcd(b,a%b);
}
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
int res=0;
for(int i=1;i<=n;i++){
if(n%i==0){
int s=0;
for(int j=1;j<=i;j++){
for(int k=j;k<=n;k+=i) {
s=gcd(s,abs(a[k]-a[j]));
}
}
if(s!=1) res++;
}
}
cout<<res<<endl;
}
}