题目描述
给定两个长度相等的字符串,保证字符串之间差奇数个,请求出排中间的字符串是多少
输入格式
第一行,一个正整数n表示字符串长度
接下来2行,表示两个长度为n的字符串
输出格式
一行,表示位于中间的字符串
输入样例
2
az
bf
输出样例
bc
数据范围
对于前50% n<=1,000
对于 100% n<=200,000
标程:
题目描述
给定n个数,问最少选几个数,使他们的gcd为1
输入格式
第一行一个正整数n
第二行,共n个数表示ai
输出格式
输出 1 行,表示答案,若不存在则输出-1
输入样例
3
10 6 15
输出样例
3
数据范围
对于40% 保证 n<=20
对于另外20% 保证 n<=1000,ai<=2000
对于100% 保证 1<=n,ai<=300000
标程:
题目描述
有 n本书,第 i 本书中有 ai 个问题,均属于第 ti 类问题。
有 q 次询问,每次询问给出一个区间 [li,ri] ,询问有多少个原序列的连续子区间是给出区间的子区间,且该子区间中所有书中问题的和满足第 1 类的问题恰好比第 2 类的问题恰好多 k 个。
输入格式
第一行,两个正整数n,k
第二行,共n个数,表示ti
第三行,共n个数,表示ai
第四行,一个正整数q
接下来q行,每行两个数li,ri
输出格式
共q行,表示答案
输入样例
4 1
1 1 1 2
1 1 1 1
4
1 2
1 3
1 4
3 4
输出样例
2
3
4
1
数据范围
20 % : n,q<=10
50 % : n,q<=2,000
100 % :n,q<=100,000,0<=ai<=1e9,1<=ti<=2,-1e9<=k<=1e9
标程:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 110000;
int n,q,Q;
int t[MAXN],a[MAXN];
ll k,sum[MAXN],A[MAXN],B[MAXN];// A -> -k / B -> +k
map<ll,int> S;int tmpcnt = 0;
struct Query{
int l,r,id;
}qu[MAXN];
bool cmp(Query a,Query b){
if(a.l/Q != b.l/Q)
return a.l / Q < b.l / Q;
else
return ((a.l/Q)&1)?a.r < b.r:a.r > b.r;
}
void init(){
scanf("%d %lld",&n,&k);
for(int i = 1;i<=n;i++) scanf("%d",&t[i]);
for(int i = 1;i<=n;i++) scanf("%d",&a[i]);
for(int i = 1;i<=n;i++){
sum[i] = t[i] == 1?a[i]:-a[i];
sum[i] += sum[i-1];
S[sum[i]] = 0;
}
S[0] = 0;
for(auto it = S.begin();it != S.end();it++)
it->second = ++tmpcnt;
for(int i = 0;i<=n;i++){
if(S.count(sum[i]-k)) A[i] = S[sum[i]-k];
if(S.count(sum[i]+k)) B[i] = S[sum[i]+k];
sum[i] = S[sum[i]];
}
Q = sqrt(n);
scanf("%d",&q);
for(int i = 1;i<=q;i++)
scanf("%d %d",&qu[i].l,&qu[i].r),qu[i].id = i;
sort(qu+1,qu+q+1,cmp);
}
static int cnt[MAXN],L = 1,R = 0;// cnt 维护 [L-1,R] 的前缀和
ll ans = 0;
void addL(int pos){
ans += cnt[B[pos-1]];cnt[sum[pos-1]]++;
}
void addR(int pos){
ans += cnt[A[pos]];cnt[sum[pos]]++;
}
void delL(int pos){
cnt[sum[pos-1]]--;ans -= cnt[B[pos-1]];
}
void delR(int pos){
cnt[sum[pos]]--;ans -= cnt[A[pos]];
}
ll ANS[MAXN];
void solve(){
cnt[S[0]] = 1;
for(int i = 1;i<=q;i++){
while(qu[i].l < L) addL(--L);
while(qu[i].r > R) addR(++R);
while(qu[i].l > L) delL(L++);
while(qu[i].r < R) delR(R--);
ANS[qu[i].id] = ans;
}
for(int i = 1;i<=q;i++){
printf("%lld\n",ANS[i]);
}
}
int main(){
init();
solve();
return 0;
}