【Henu ACM Round#19 D】 Points on Line

【链接】 我是链接,点我呀:)
【题意】

在这里输入题意

【题解】

考虑l..r这个区间。
且r是满足a[r]-a[l]<=d的最大的r

如果是第一个找到的区间,则直接累加C(r-l+1,3);
然后l++

然后考虑这个区间之后的下一个区间[l+1,R],这里R是满足a[R]-a[l+1]<=d的最大的R

如果R==r的话,l=l+1,continue;

否则。
如果l+1>r的话累加C(R-(l+1)+1,3);
如果l+1<=r的话
显然l..r和l+1..R之间有一个公共的部分[l+1..r]以及第二个区间独立的部分[r+1..R]
枚举i从0..2然后从第一个公共部分中取出i个位置,然后从第二个独立的部分中取出3-i个位置就好
这样可以保证不会和之前取的3元组重复
然后l=l+1,continue

【代码】

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 1e5;

int n,d,a[N+10];

ll xuan(int l,int r,int x){
    ll len = r-l+1;
    if (x>len) return 0;
    if (x==0) return 1;
    if (x==1){
        return len;
    }
    if (x==2)
        return len*(len-1)/2;
    else
        return len*(len-1)*(len-2)/6;
}

int main()
{
    #ifdef LOCAL_DEFINE
        freopen("rush_in.txt","r",stdin);
    #endif
    ios::sync_with_stdio(0),cin.tie(0);
    cin >> n>>d;
    for (int i=1;i <=n;i++) cin >> a[i];
    if (n<3){
        cout<<0<<endl;
        return 0;
    }
    int l = 1,r = 2,prer=-1;
    long long ans = 0;
    while (1){
        if (r<=l) r = l + 1;
        if (l==n-1) break;
        while (r+1<=n && a[r+1]-a[l]<=d) r++;
        if (a[r]-a[l]<=d){
            if (prer==-1){
                ans = ans + xuan(l,r,3);
            }else{
                if (prer<r){
                    if (l>prer){
                        ans+=xuan(l,r,3);
                    }else{
                        for (int i = 0;i <= 2;i++)
                            ans+=xuan(l,prer,i)*xuan(prer+1,r,3-i);
                    }
                }
            }
            prer = r;
        }
        l++;
    }
    cout<<ans<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/AWCXV/p/8398272.html

时间: 2024-07-31 02:45:53

【Henu ACM Round#19 D】 Points on Line的相关文章

【Henu ACM Round#19 E】 Om Nom and Candies

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 紫书上的原题: 链接 [代码] #include <bits/stdc++.h> #define ll long long using namespace std; const int N = 1e5; ll m,c1,c2,v1,v2; int main() { #ifdef LOCAL_DEFINE freopen("rush_in.txt","r",stdin); #endif i

【Henu ACM Round#19 B】 Luxurious Houses

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 从右往左维护最大值. 看到比最大值小(或等于)的话.就递增到比最大值大1就好. [代码] #include <bits/stdc++.h> using namespace std; const int N = 1e5; int a[N+10],n; int main() { cin >> n; for(int i = 1;i <= n;i++) cin >> a[i]; int now=0; fo

【Henu ACM Round#19 C】 Developing Skills

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 优先把不是10的倍数的变成10的倍数. (优先%10比较大的数字增加 如果k还有剩余. 剩下的数字都是10的倍数了. 那么先加哪一个都可以了. [代码] #include <bits/stdc++.h> using namespace std; const int N = 1e5; int a[N+10],n,k; int b[N+10]; int point = 0; int main() { ios::sync_with_

【Henu ACM Round#19 A】 Vasya the Hipster

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 模拟题. 两个一起用->min(a,b); 剩下的除2加上去就好 [代码] #include <bits/stdc++.h> using namespace std; int a,b; int main() { cin >> a >> b; cout<<min(a,b)<<' '<<abs(a-b)/2<<endl; return 0; } 原文地址

【Henu ACM Round #13 C】 Ebony and Ivory

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 先求出c-bx的所有可能 ->存在map里面 然后枚举y看看ay在不在map里面 在的话就有解. 这样复杂度是\(O(N*log_2N)\)的 比直接两层循环枚举的\(O(N^2)\)复杂度要来的好 这种方法也叫"中途相遇法" [代码] #include <bits/stdc++.h> #define ll long long using namespace std; ll a,b,c; map<

【Henu ACM Round #13 B】Spider Man

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 会发现每个环可以操作的次数是固定的. (环的大小-1 也就是说一旦环确定了.其实结果就已经确定了. 则直接看操作总数的奇偶性就可以了. [代码] #include <bits/stdc++.h> #define long long using namespace std; int n,x; int main(){ #ifdef LOCAL_DEFINE freopen("rush_in.txt", &quo

【Henu ACM Round #13 D】A Trivial Problem

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 123...n中末尾0的个数 只会由素因子2和5的个数决定且等于 Min{cnt[2],cnt[5]} 且素因子2的个数一定会比5多; 所以n!的末尾0的个数 等于for (int i = 1;i <= n;i++)中所有i的5因子的个数和 枚举一下就好 [代码] #include <bits/stdc++.h> using namespace std; const int N = 1e7; int n; vector&

【Henu ACM Round #13 E】Spy Syndrome 2

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 对m个串建立一棵字典树. 然后对主串. 尝试从第一个位置开始.在字典树中尝试匹配 如果匹配到了位置i 就再从位置i+1开始尝试匹配 (这时又重新从根节点开始重新匹配 每次匹配最多只要往下走50步. 写个递归的过程就好. [代码] #include <bits/stdc++.h> using namespace std; const int N = 1e6; const int NN = 1e4; const int M = 1

【Henu ACM Round#14 A】Vitaly and Night

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 连续两个如果不全是0就递增cnt [代码] #include <bits/stdc++.h> using namespace std; int n,m; int main() { cin >> n >>m; int cnt = 0; for (int i = 1;i <= n;i++){ int x,y; for (int j = 1;j <= m;j++){ cin >>x &