ZOJ4003 双指针+计数

题目链接
给了两个序列 X Y
定义sub 连续的等长的X Y Σ ( x_i-y_j)p <=V 有多少种方案数
不难发现 这种连续的求和 逐渐增大 那么可以用双指针优化 ,也就是遍历到以i 开头 j开头时 可以删除左边的元素 直到当前求和<=V 记录下方案数

#include<bits/stdc++.h>
#include<stdlib.h>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<time.h>
#include <cstdio>
#include <iostream>
#include <vector>
#define ll long long
#define int long long
#define inf 0x3f3f3f3f
#define mods 1000000000007
#define modd 998244353
#define PI acos(-1)
#define fi first
#define se second
#define lowbit(x) (x&(-x))
#define mp make_pair
#define pb push_back
#define si size()
#define E exp(1.0)
#define fixed cout.setf(ios::fixed)
#define fixeds(x) setprecision(x)
#define IOS ios::sync_with_stdio(false);cin.tie(0)
 using namespace std;
 ll gcd(ll a,ll b){
    
    if(a<0)a=-a;if(b<0)b=-b;return b==0?a:gcd(b,a%b);}
template<typename T>void read(T &res){
    
    bool flag=false;char ch;while(!isdigit(ch=getchar()))(ch=='-')&&(flag=true);
for(res=ch-48;isdigit(ch=getchar());res=(res<<1)+(res<<3)+ch - 48);flag&&(res=-res);}
ll lcm(ll a,ll b){
    
    return a*b/gcd(a,b);}
ll qp(ll a,ll b,ll mod){
    
    ll ans=1;if(b==0){
    
    return ans%mod;}while(b){
    
    if(b%2==1){
    
    b--;ans=ans*a%mod;}a=a*a%mod;b=b/2;}return ans%mod;}//快速幂%
ll qpn(ll a,ll b, ll p){
    
    ll ans = 1;a%=p;while(b){
    
    if(b&1){
    
    ans = (ans*a)%p;--b;}a =(a*a)%p;b >>= 1;}return ans%p;}//逆元   (分子*qp(分母,mod-2,mod))%mod;
ll a[100001];
ll b[100001];
ll cnt[20009];
ll vel[20009];
ll p;
ll check(ll x,ll y){
    
    
ll ok=abs(a[x]-b[y]);
ll res=1;
for(int i=1;i<=p;i++){
    
    
    res=res*ok;
}
return res;
}
signed main(){
    
    
ll t;
read(t);
while(t--){
    
    
ll n,V;
read(n);
read(V);
read(p);
memset(cnt,0,sizeof(cnt));
memset(vel,0,sizeof(vel));
for(int i=1;i<=n;i++){
    
    
  read(a[i]);
}
for(int i=1;i<=n;i++){
    
    
read(b[i]);
}
 ll ans=0;
for(int i=1;i<=n;i++){
    
    
 for(int j=1;j<=n;j++){
    
    
 ll pos=i-j+n;
 cnt[pos]++;
 vel[pos]+=check(i,j);
 while(cnt[pos]>0&&vel[pos]>V){
    
    
  cnt[pos]--;
  vel[pos]-=check(i-cnt[pos],j-cnt[pos]);

 }
 ans=ans+cnt[pos];

 }

}
 printf("%lld\n",ans);
}
}

猜你喜欢

转载自blog.csdn.net/weixin_45948940/article/details/109078313