A:
维护下x,y,z数量的前缀和,三者中最大数量-最小数量<=1就能结束。
code:
#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <set>
#include <map>
using namespace std;
#define N 200100
#define ALL(x) x.begin(),x.end()
#define CLR(x,a) memset(x,a,sizeof(x))
typedef pair<int,int> PI;
typedef long long ll;
const ll INF = 0x3fffffff;
const int MOD = 7;
const double EPS = 1e-7;
string s;
int cnt[N][3];
char *solve(int x,int y)
{
if(y-x<3) return "YES";
int Max=-1,Min=INF;
for(int j=0;j<3;j++){
Max=max(Max,cnt[y][j]-cnt[x][j]);
Min=min(Min,cnt[y][j]-cnt[x][j]);
}
if(Max-Min<=1) return "YES";
return "NO";
}
int main()
{
cin>>s;
int n=s.size();
for(int i=1;i<=n;i++){
for(int j=0;j<3;j++) cnt[i][j]=cnt[i-1][j];
if(s[i-1]=='x') cnt[i][0]++;
if(s[i-1]=='y') cnt[i][1]++;
if(s[i-1]=='z') cnt[i][2]++;
}
int m;
scanf("%d",&m);
while(m--){
int x,y;
scanf("%d%d",&x,&y);
printf("%s\n", solve(x-1,y));
}
return 0;
}
两个指针维护下。具体看代码。
code:
#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <set>
#include <map>
using namespace std;
#define N 200100
#define ALL(x) x.begin(),x.end()
#define CLR(x,a) memset(x,a,sizeof(x))
typedef pair<int,int> PI;
typedef long long ll;
const ll INF = 0x3fffffff;
const int MOD = 7;
const double EPS = 1e-7;
int a[N],x;
map<int,int> cnt,b;
vector<int> ans;
int main()
{
int n,m,p;
scanf("%d%d%d",&n,&m,&p);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
for(int i=0;i<m;i++) scanf("%d",&x), b[x]++;
for(int i=0;i<p;i++){
if(i+1ll*(m-1)*p>=n) break;
ll j;
cnt=b;
for(j=i;j<=i+1ll*(m-1)*p;j+=p)
if(--cnt[a[j]]==0) cnt.erase(a[j]);
if(cnt.size()==0) ans.push_back(i+1);
for(ll k=i;j<n;j+=p,k+=p){
if(--cnt[a[j]]==0) cnt.erase(a[j]);
if(++cnt[a[k]]==0) cnt.erase(a[k]);
if(cnt.size()==0) ans.push_back(k+p+1);
}
}
sort(ALL(ans));
printf("%d\n", ans.size());
for(int i=0;i<ans.size();i++)
printf("%d ", ans[i]);
return 0;
}
C:
题意:
构造一个序列a,使得序列中两个不相等的数x,y。存在a[i]=x,a[i+1]=y或a[i]=y,a[i+1]=x。现在有m个互不相等的数字可以使用,每种可以使用无限次,但是需要花费一定费用先购买这种数字。求最大花费。
题解看这里,在最下面的例题。
code:
#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <set>
#include <map>
using namespace std;
#define N 100010
#define ll long long
#define ALL(x) x.begin(),x.end()
#define CLR(x,a) memset(x,a,sizeof(x))
typedef pair<int,int> PI;
const int INF=0x3fffffff;
const int MOD =1000000007;
const double EPS=1e-7;
int n,m;
int a[N];
bool check(ll x){
if(x%2) return x*(x-1)/2+1<=n;
else return x*(x-1)/2+x/2<=n;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++) scanf("%*d%d",a+i);
sort(a,a+m);
reverse(a,a+m);
ll l=1,r=m+1;
while(l<r){
ll mid=(l+r)>>1;
if(check(mid)) l=mid+1;
else r=mid;
}
ll ans=0;
for(int i=0;i<m && i<(r-1);i++) ans+=a[i];
printf("%I64d\n",ans);
return 0;
}